When it comes to Object Oriented Programming, there is no shortage of guidelines and principles for how to properly design an OO system. There is also no shortage of acronyms to describe these principles: DRY, SRP, LSP, LoD, ISP, OCP, etc. However, there are two acronyms that really shine through to describe how to, and how not to do OOP well. The two acronyms are SOLID and STUPID (respectively).
14. Classic View
$lion = new Lion;
$lion->roar();
$lion->walkTo($point);
$lion->hunt($zebra);
$lion->sleep();
Does A Lion Have
A Button To Make
It Roar?
15. Classic View
$lion = new Lion;
$lion->roar();
$lion->walkTo($point);
$lion->hunt($zebra);
$lion->sleep();
Does A Lion Have
A Button To Make
It Roar?What Does It
Mean For An
Object To “Hunt”?
16. Classic View
$lion = new Lion;
$lion->roar();
$lion->walkTo($point);
$lion->hunt($zebra);
$lion->sleep();
Does A Lion Have
A Button To Make
It Roar?What Does It
Mean For An
Object To “Hunt”?
What Is A Lion In
Relation To Our
Application?
22. “Modern” View
Object == Collection Of (Related)
Behaviors
Methods == Behavior
Properties == Details Of Behavior
23. Classic View == “(conceptually) is a”
Modern View == “behaves as a”
24. interface Number {
function getValue();
function __toString();
function add(Number $n);
function subtract(Number $n);
function equals(Number $n);
function isLessThan(Number $n);
function isGreaterThan(Number $n);
}
33. Polymorphic Code
class Integer implements Number {
public function add(Number $a) {
return new Integer(
$this->getValue() +
(int) $a->getValue()
);
}
}
34. Polymorphic Code
class Float implements Number {
public function add(Number $a) {
return new Float(
$this->getValue() +
(float) $a->getValue()
);
}
}
60. S - Single Responsibility Principle
O-
L -
I -
D-
A Good API
Does One
Thing
61.
62.
63. S - Single Responsibility Principle
O- Open / Closed Principle
L -
I -
D-
A Good API
Never Changes
64.
65.
66.
67.
68.
69. S - Single Responsibility Principle
O- Open / Closed Principle
L - Liskov Substitution Principle
I -
D-
A Good API
Behaves Like
Its Contract
70.
71.
72.
73. S - Single Responsibility Principle
O- Open / Closed Principle
L - Liskov Substitution Principle
I - Interface Segregation Principle
D-
A Good API
Has A Narrow
Responsibility
74.
75. S - Single Responsibility Principle
O- Open / Closed Principle
L - Liskov Substitution Principle
I - Interface Segregation Principle
D- Dependency Inversion Principle
A Good API
Depends Upon
Abstractions
76.
77.
78. S - Single Responsibility Principle
O- Open / Closed Principle
L - Liskov Substitution Principle
I - Interface Segregation Principle
D- Dependency Inversion Principle
105. What Good OOP Gives You
Modular Code
Reusable Code
Extendable Code
Easy To Read Code
Maintainable Code
Easy To Change Code
Easy To Understand Code
Clean Abstractions (mostly)
106. What Good OOP Costs You
Tends To Have More “Layers”
Tends To Be Slower At Runtime
Tends To Have Larger Codebases
Tends To Result In Over-Abstraction
Tends To Require More Effort To Write
Tends To Require More Tacit Knowledge
108. interface Car {
public function turnLeft();
public function turnRight();
public function goFaster();
public function goSlower();
public function shiftUp();
public function shiftDown();
public function start();
}
109. interface Steerable {
public function steer($angle);
}
interface Acceleratable {
public function accelerate($amt);
}
interface Shiftable {
public function shiftDown();
public function shiftUp();
}
113. interface MailSystemInterface {
public function format(array $message);
public function mail(array $message);
}
What Responsibility?
Formatting Messages
114. interface MailSystemInterface {
public function format(array $message);
public function mail(array $message);
}
What Responsibility?
Formatting Messages
Encoding Messages
115. interface MailSystemInterface {
public function format(array $message);
public function mail(array $message);
}
What Responsibility?
Formatting Messages
Encoding Messages
Assembling Headers
116. interface MailSystemInterface {
public function format(array $message);
public function mail(array $message);
}
What Responsibility?
Formatting Messages
Encoding Messages
Assembling Headers
Calling Sendmail
117. interface MailSystemInterface {
public function format(array $message);
public function mail(array $message);
}
What Responsibility?
Formatting Messages
Encoding Messages
Assembling Headers
Calling Sendmail
Setting INI settings…?
118. interface MailSystemInterface {
public function format(array $message);
public function mail(array $message);
}
What Responsibility?
Open For Extension?
119. interface MailSystemInterface {
public function format(array $message);
public function mail(array $message);
}
What Responsibility?
Open For Extension?
Edits Require
Copy/Paste
120. interface MailSystemInterface {
public function format(array $message);
public function mail(array $message);
}
What Responsibility?
Open For Extension?
Liskov Substitution...
121. interface MailSystemInterface {
public function format(array $message);
public function mail(array $message);
}
What Responsibility?
Open For Extension?
Liskov Substitution...
One Interface...
Many Responsibilites
122. interface MailSystemInterface {
public function format(array $message);
public function mail(array $message);
}
What Responsibility?
Open For Extension?
Liskov Substitution...
One Interface...
What Dependencies?
123. interface MessageFormatter {
public function format(Message $message);
}
interface MessageEncoder {
public function encode(Message $message);
}
interface MessageTransport {
public function send(Message $message);
}
124. class MailSystem {
public function __construct(
MessageFormatter $messageFormatter,
MessageEncoder $messageEncoder,
MessageTransport $messageTransport
) {}
public function mail(Message $message);
}