Post on 27-Jun-2015
OOPOOPWhat? Why?What? Why?
on Rails?on Rails?
\\
earliest evidence of double-entry bookkeeping earliest evidence of double-entry bookkeeping is the Farolfi ledger of 1299-1300.is the Farolfi ledger of 1299-1300.
The earliest evidence of
full double-entry bookkeeping
is the Farolfi ledger of 1299-1300.
Why am I talking about this?
The earliest evidence of
full double-entry bookkeeping
is the Farolfi ledger of 1299-1300.
Why am I talking about this?
...because we are amazingly lucky that our idea creators are still alive!
Barbara Liskov
ACM Turing Award lecture (2009) 11:50http://www.infoq.com/presentations/liskov-power-of-abstraction
The entire system should be broken up into
“Partitions”
Each has access to some hidden state
Each provides operations
Only interact by calling each others operations
Why doesn't she get to the point?
She's talking about 'Objects'!
Why doesn't she get to the point?
She's talking about 'Objects'!
Object Oriented Programming didn't exist...
Who invented OOP?
Alan Kay is credited with coining the term
Led research to develop SmallTalk
=> 1972 (40ish years ago)
Who invented OOP?
It developed later as the dominant methodology
when programming languages supporting
the techniques became widely available
(C++, Java, Delphi)
=> early-mid 1990s (20ish years ago)
"Actually I made up the term "object-oriented", and I can tell you I did not have C++ in mind."
-- Alan Kay
I thought of objects
being like biological cells
and/or individual computers on a network,
only able to communicate with messages
(so messaging came at the very beginning)
– Alan Kay
Design is *all* about Dependencies
If you refer to something
---> you depend on it
When the things you depend on change
---> you must change
-- Sandi Metz, "Solid Design" GoRuCo 2009
A----\
B-----\
C -----> X
D-----/
E ---/
● if x changes everybody has to change!● x better not change! It should be stable
/--> A
/---> B
Z ------> C
\---> D
\--> E
● if z changes no body cares!● if c changes, only z may have to● z is isolated!
J K L→ →
● if L changes, K may have to● Maybe J will too?
OO Design in Rails?
ActiveRecord / Objects?
Rather than asking for data,
tell a class to do something for you
ActiveRecord / Objects?
Procedural gets info, then makes decision
ActiveRecord / Objects?
Procedural gets info, then makes decision
Object Oriented code tells objects to do things
ActiveRecord / Objects?
Procedural gets info, then makes decision
Object Oriented code tells objects to do things
What do you do in Rails code?
S.O.L.I.D
S: SRP: Single Responsibility Principle
O: OCP: Open/Closed Principle
L: LSP: Liskov Substitution Principle
I: ISP: Interface Segregation Principle
D: DIP: Dependency Inversion Principle
Single Responsibility
An object should have only a single responsibility
One and ONLY ONE reason to change
If you have to use the word “AND” or “OR”to describe your class....
Jim Weirich talk on SOLID
Jim asked: AR mixes domain + persistence -- is it ok?
Jim Weirich talk on SOLID
Jim asked: AR mixes domain + persistence -- is it ok?
Response: ● NO! As design gets complex and interactions
between objects get complex, it confuses things.
● NO! It's harder to test.
Jim Weirich talk on SOLID
Jim asked: AR mixes domain + persistence -- is it ok?
Response:● NO! As design gets complex and interactions
between objects get complex, it confuses things.● NO! It's harder to test.
Jim said: Maybe it IS OK in your case...!● IT'S PRINCIPLES NOT RULES! up to you!
The DHH Factor
...later on twitter
@paulc: ... What are your thoughts on separating logic + persistence?
The DHH Factor
...later on twitter
@paulc: ... What are your thoughts on separating logic + persistence?
@dhh: Fuck. That. Shit. Same complete wank. "Rails is not your application".
If you're building a web app, of course it is.
#find and the infinite protocol
If ActiveRecord models
Are your Domain Models
You are exposing an infinite protocol!
.where(:category => “Blah”).order(:name)
Interface Segregation Principle
Code should depend on as NARROW protocol as possible
The protocol is the messages between objects
Not WIDE interfaces!
It's just encapsulation, right?
#find and the infinite protocol
If ActiveRecord models
Are your Domain Models
You are exposing an infinite protocol!
.find(:first)
Single Responsibility
Build models without referencing ActiveRecord?
Why?● Faster tests● Separate concerns for complex situations● Expose a clean, domain-oriented interface● Logic unrelated to persistence:
At the intersection of persistable objectsYou often find business rules. IT'S A THIRD PLAIN RUBY OBJECT!
Single Responsibility
Build models without referencing ActiveRecord?
How?● FigLeaf approach?
– The gem “hides” all AR methods (so you can't access them outside your model)
– You expose the functionality you mean
– It's domain driven
Single Responsibility
Build models without referencing ActiveRecord?
How?● Domain Object approach?
– You keep AR models as thin as possible
– Add a separate object for Domain logicthat accesses the AR model
– Everybody else accesses the Domain object
...thoughts
“There is no problem in computer science
that cannot be solved by adding another layer of indirection,
except having too many layers of indirection”
...thoughts
@dhh
I hate the disconnect between design patterns/abstract ideas and implementation
Your basic question should be “Is the code better?”
...thoughts
@avdi
You absolutely MUST not give up the fun you found when first coming to ruby when working on larger systems
...your thoughts?