5. SINGLE RESP. P.
object should have only a single
responsibility
- AR::Base - Presistency only
- AR::Controller - REquest care only
6. SRP - Basic
class User < AR::Base
def can_modify_article? article
article.user == self
end
before_save :create_activity
def create_activity
Activity.new :message => 'New user #{name}'
end
end
7. SRP - Basic
class User < AR::Base; end
class ArticlePolicy
def can_user_modify_article? user, article
article.user == user
end
end
class UserObserver
def after_save record
Activity.new :message => 'New user #{record.name}'
end
end
8. SRP - Advanced
class User < AR::Base
end
class ArticleForSignup
include ActiveModel::Validations
validate :name, :presence => true
attr_accessor :name
end
9. OPEn/close p.
an object should be open for
extensions but close for modifications
- ruby is dynamic lang. so modifying
object is its nature
- meta-programming (use with care)
10. Ocp - basic
class Array
def to_s
self.map { |x| x.to_s }.join(', ')
end
end
11. Ocp - intermediate
class Invoice
def to_s
formater = HTMLFormater.new
formater.format self
end
end
class Invoice
def to_s formater = HTMLFormater.new
formater.format self
end
end
13. DI - BASIC
class Error
def initialize
@reporter = Reporter.new
end
def report
@reporter.report self
end
end
class Error
def initialize reporter = Reporter.new
@reporter = reporter
end
end
14. DI - More abstract
class Error
def initialize(options = {})
@reporter = options[:reporter] || Reporter.new
end
end
class Error
def initialize(options = {})
@reporter = (options[:reporter_name] || 'reporter').classify.new
end
end
15. Liskov D. P.
objects in a program should be
replaceable with instances of their
subtypes without altering the
correctness of that program
- method missing
- super-class is smarter than its
children
16. Liskov - AR::Base
class User < AR::Base
# create_table :users { |t| t.text :logger }
end
# We expect ...
user = User.new
user.logger = "syslog-ng"
# => "syslog-ng"
# but we get
user = User.new
user.logger = "syslog-ng"
# => #<ActiveSupport::BufferedLogger:0x00000000b6de38 ..>
17. Interface seg.
many client specific interfaces are
better than one general purpose
interface
- one smart controller
18. ISP
class Signup < ApplicationController
def create
if params[:type] == 'founder'
item = Founder.new(params)
end
...
end
end
class FounderSignup < ApplicationController
end
class AdvisorSignup < ApplicationController
end
20. Why?
If your application is successful you
will have to change it as new
requirements will come or new
improvements will be introduced.
Refactor not because you know the
abstraction but because you want
to find it.
21. REality 2 imp.
Customers should come to you with
specific, tangible, measurable,
external objectives that you can than
implement and come up with
abstractions. The reason is because
people relate very well to concrete
stuff in our world then to abstract,
emotional descriptions.
22. examples
- Make my customers feel more happy,
What means more happy?
- The signup has to be simple. What it
means simple?
- I need more leads/customers to come
to my shop.. How do you measure more?
23. Best practice
The path from abstract descriptions
of our customers to concrete
examples and back to abstract
concepts so we can change stuff
easily in future.