0
Don’t Be STUPID
Grasp SOLID!
Anthony Ferrara
Let’s Talk
Object
Oriented
Programming
What
Is An
Object?
Classic View
Object == Physical “Thing”
Classic View
Object == Physical “Thing”
Methods == Actions on “Thing”
Classic View
Object == Physical “Thing”
Methods == Actions on “Thing”
Properties == Description of “Thing”
Animal
MammalBird Fish
CatCow Dog
Lion Feline Cheetah
Classic View
$lion = new Lion;
$lion->roar();
$lion->walkTo($point);
$lion->hunt($zebra);
$lion->sleep();
Is This Realistic?
Classic View
$lion = new Lion;
$lion->roar();
$lion->walkTo($point);
$lion->hunt($zebra);
$lion->sleep();
(9 Months Later)
Classic View
$lion = new Lion;
$lion->roar();
$lion->walkTo($point);
$lion->hunt($zebra);
$lion->sleep();
Classic View
$lion = new Lion;
$lion->roar();
$lion->walkTo($point);
$lion->hunt($zebra);
$lion->sleep();
Does A Lion Have...
Classic View
$lion = new Lion;
$lion->roar();
$lion->walkTo($point);
$lion->hunt($zebra);
$lion->sleep();
Does A Lion Have...
Classic View
$lion = new Lion;
$lion->roar();
$lion->walkTo($point);
$lion->hunt($zebra);
$lion->sleep();
Does A Lion Have...
The Classical
Model Is Easy To
Understand
The Classical
Model Is
Completely
Impractical
“Modern” View
Object == Collection Of (Related)
Behaviors
“Modern” View
Object == Collection Of (Related)
Behaviors
Methods == Behavior
“Modern” View
Object == Collection Of (Related)
Behaviors
Methods == Behavior
Properties == Details Of Behavior
Classic View == “(conceptually) is a”
Modern View == “behaves as a”
interface Number {
function getValue();
function __toString();
function add(Number $n);
function subtract(Number $n);
func...
Number
IntegerFloat Decimal
longshort long long
unsigned signed
But Wait!
We Don’t Even
Need Inheritance
All We Need Is
Polymorphism
And Encapsulation
Polymorphism
Behavior Is Determined Dynamically
“Dynamic Dispatch”
Procedural Code
if ($a->isLong()) {
return new Long($a->getValue() + 1);
} elseif ($a->isFloat()) {
return new Float($a->g...
Polymorphic Code
return $number->add(new Integer(1));
Polymorphic Code
class Integer implements Number {
public function add(Number $a) {
return new Integer(
$this->getValue() ...
Polymorphic Code
class Float implements Number {
public function add(Number $a) {
return new Float(
$this->getValue() +
(f...
Encapsulation
Behavior Is Completely Contained By
The Object’s API
(Information Hiding)
Procedural Code
if (5 == $number->value) {
print “Number Is 5”;
} else {
print “Number Is Not 5”;
}
Encapsulated Code
if ($number->equals(new Integer(5))) {
print “Number Is 5”;
} else {
print “Number Is Not 5”;
}
Encapsulated Code
class Decimal implements Number {
protected $intValue;
protected $exponent;
public function equals(Numbe...
Behavior Is
Defined By The
API
Two Types Of Primitive APIs
Interfaces (Explicit)
Two Types Of Primitive APIs
Interfaces (Explicit)
Duck Typing (Implicit)
If an Object Is A
Collection Of
Behaviors...
What Is A
Collection Of
Classes/Objects?
APIs
Method
APIs
Method MethodMethod
Class
APIs
Method MethodMethod
Class ClassClass
Package
APIs
Method MethodMethod
Class ClassClass
Package PackagePackage
Library
APIs
Method MethodMethod
Class ClassClass
Package PackagePackage
Library
Framework
LibraryLibrary
What Makes A
Good API?
A Good API
Does One Thing
A Good API
Never Changes
A Good API
Behaves Like Its
Contract
A Good API
Has A Narrow
Responsibility
A Good API
Depends Upon
Abstractions
And That’s
SOLID
Code
S - Single Responsibility Principle
O-
L -
I -
D-
A Good API
Does One
Thing
S - Single Responsibility Principle
O- Open / Closed Principle
L -
I -
D-
A Good API
Never Changes
S - Single Responsibility Principle
O- Open / Closed Principle
L - Liskov Substitution Principle
I -
D-
A Good API
Behaves...
S - Single Responsibility Principle
O- Open / Closed Principle
L - Liskov Substitution Principle
I - Interface Segregation...
S - Single Responsibility Principle
O- Open / Closed Principle
L - Liskov Substitution Principle
I - Interface Segregation...
S - Single Responsibility Principle
O- Open / Closed Principle
L - Liskov Substitution Principle
I - Interface Segregation...
Note That SOLID
Does Not Dictate
What Is Good OOP
SOLID Emerges
From Good OOP
So, What Makes
A Bad API?
Global Variables
(Spooky Action
At A Distance)
Depending On
Specifics Of An
Implementation
Hidden
Dependencies
Unhealthy Focus
On Performance
Poorly Named
APIs
Duplication
And That’s
STUPID
Code
S - Singletons
T -
U -
P -
I -
D-
Global Variables
(Spooky Action
At A Distance)
S - Singletons
T - Tight Coupling
U -
P -
I -
D-
Depending On
Specifics Of An
Implementation
S - Singletons
T - Tight Coupling
U - Untestable Code
P -
I -
D-
Hidden
Dependencies
S - Singletons
T - Tight Coupling
U - Untestable Code
P - Premature Optimization
I -
D-
Unhealthy Focus
On Performance
S - Singletons
T - Tight Coupling
U - Untestable Code
P - Premature Optimization
I - Indescriptive Naming
D-
Poorly Named
...
S - Singletons
T - Tight Coupling
U - Untestable Code
P - Premature Optimization
I - Indescriptive Naming
D- Duplication
D...
S - Singletons
T - Tight Coupling
U - Untestable Code
P - Premature Optimization
I - Indescriptive Naming
D- Duplication
STUPID
Embodies
Lessons Learned
From Bad OOP
What Good OOP Gives You
Modular Code
Reusable Code
Extendable Code
Easy To Read Code
Maintainable Code
Easy To Change Code...
What Good OOP Costs You
Tends To Have More “Layers”
Tends To Be Slower At Runtime
Tends To Have Larger Codebases
Tends To ...
Let’s Look At
Some Code!
interface Car {
public function turnLeft();
public function turnRight();
public function goFaster();
public function goSlo...
interface Steerable {
public function steer($angle);
}
interface Acceleratable {
public function accelerate($amt);
}
inter...
Let’s Look At
Drupal Code!
interface MailSystemInterface {
public function format(array $message);
public function mail(array $message);
}
interface MailSystemInterface {
public function format(array $message);
public function mail(array $message);
}
What Respo...
interface MailSystemInterface {
public function format(array $message);
public function mail(array $message);
}
What Respo...
interface MailSystemInterface {
public function format(array $message);
public function mail(array $message);
}
What Respo...
interface MailSystemInterface {
public function format(array $message);
public function mail(array $message);
}
What Respo...
interface MailSystemInterface {
public function format(array $message);
public function mail(array $message);
}
What Respo...
interface MailSystemInterface {
public function format(array $message);
public function mail(array $message);
}
What Respo...
interface MailSystemInterface {
public function format(array $message);
public function mail(array $message);
}
What Respo...
interface MailSystemInterface {
public function format(array $message);
public function mail(array $message);
}
What Respo...
interface MailSystemInterface {
public function format(array $message);
public function mail(array $message);
}
What Respo...
interface MailSystemInterface {
public function format(array $message);
public function mail(array $message);
}
What Respo...
interface MailSystemInterface {
public function format(array $message);
public function mail(array $message);
}
What Respo...
interface MessageFormatter {
public function format(Message $message);
}
interface MessageEncoder {
public function encode...
class MailSystem {
public function __construct(
MessageFormatter $messageFormatter,
MessageEncoder $messageEncoder,
Messag...
Principle Of
Good
Enough
Know the rules well
so you can break them
effectively...
Dalai Lama XIV
Anthony Ferrara
@ircmaxell
blog.ircmaxell.com
me@ircmaxell.com
youtube.com/ircmaxell
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Don't Be STUPID, Grasp SOLID - ConFoo Edition
Upcoming SlideShare
Loading in...5
×

Don't Be STUPID, Grasp SOLID - ConFoo Edition

1,152

Published on

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).

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,152
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
7
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Transcript of "Don't Be STUPID, Grasp SOLID - ConFoo Edition"

  1. 1. Don’t Be STUPID Grasp SOLID! Anthony Ferrara
  2. 2. Let’s Talk Object Oriented Programming
  3. 3. What Is An Object?
  4. 4. Classic View Object == Physical “Thing”
  5. 5. Classic View Object == Physical “Thing” Methods == Actions on “Thing”
  6. 6. Classic View Object == Physical “Thing” Methods == Actions on “Thing” Properties == Description of “Thing”
  7. 7. Animal MammalBird Fish CatCow Dog Lion Feline Cheetah
  8. 8. Classic View $lion = new Lion; $lion->roar(); $lion->walkTo($point); $lion->hunt($zebra); $lion->sleep();
  9. 9. Is This Realistic?
  10. 10. Classic View $lion = new Lion; $lion->roar(); $lion->walkTo($point); $lion->hunt($zebra); $lion->sleep();
  11. 11. (9 Months Later)
  12. 12. Classic View $lion = new Lion; $lion->roar(); $lion->walkTo($point); $lion->hunt($zebra); $lion->sleep();
  13. 13. 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?
  14. 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?What Does It Mean For An Object To “Hunt”?
  15. 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”? What Is A Lion In Relation To Our Application?
  16. 16. The Classical Model Is Easy To Understand
  17. 17. The Classical Model Is Completely Impractical
  18. 18. “Modern” View Object == Collection Of (Related) Behaviors
  19. 19. “Modern” View Object == Collection Of (Related) Behaviors Methods == Behavior
  20. 20. “Modern” View Object == Collection Of (Related) Behaviors Methods == Behavior Properties == Details Of Behavior
  21. 21. Classic View == “(conceptually) is a” Modern View == “behaves as a”
  22. 22. 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); }
  23. 23. Number IntegerFloat Decimal longshort long long unsigned signed
  24. 24. But Wait!
  25. 25. We Don’t Even Need Inheritance
  26. 26. All We Need Is Polymorphism And Encapsulation
  27. 27. Polymorphism Behavior Is Determined Dynamically “Dynamic Dispatch”
  28. 28. Procedural Code if ($a->isLong()) { return new Long($a->getValue() + 1); } elseif ($a->isFloat()) { return new Float($a->getValue() + 1.0); } elseif ($a->isDecimal()) { return new Decimal($a->getValue() + 1.0); }
  29. 29. Polymorphic Code return $number->add(new Integer(1));
  30. 30. Polymorphic Code class Integer implements Number { public function add(Number $a) { return new Integer( $this->getValue() + (int) $a->getValue() ); } }
  31. 31. Polymorphic Code class Float implements Number { public function add(Number $a) { return new Float( $this->getValue() + (float) $a->getValue() ); } }
  32. 32. Encapsulation Behavior Is Completely Contained By The Object’s API (Information Hiding)
  33. 33. Procedural Code if (5 == $number->value) { print “Number Is 5”; } else { print “Number Is Not 5”; }
  34. 34. Encapsulated Code if ($number->equals(new Integer(5))) { print “Number Is 5”; } else { print “Number Is Not 5”; }
  35. 35. Encapsulated Code class Decimal implements Number { protected $intValue; protected $exponent; public function equals(Number $a) { if ($a instanceof Decimal) { // Compare Directly } else { // Cast } }
  36. 36. Behavior Is Defined By The API
  37. 37. Two Types Of Primitive APIs Interfaces (Explicit)
  38. 38. Two Types Of Primitive APIs Interfaces (Explicit) Duck Typing (Implicit)
  39. 39. If an Object Is A Collection Of Behaviors...
  40. 40. What Is A Collection Of Classes/Objects?
  41. 41. APIs Method
  42. 42. APIs Method MethodMethod Class
  43. 43. APIs Method MethodMethod Class ClassClass Package
  44. 44. APIs Method MethodMethod Class ClassClass Package PackagePackage Library
  45. 45. APIs Method MethodMethod Class ClassClass Package PackagePackage Library Framework LibraryLibrary
  46. 46. What Makes A Good API?
  47. 47. A Good API Does One Thing
  48. 48. A Good API Never Changes
  49. 49. A Good API Behaves Like Its Contract
  50. 50. A Good API Has A Narrow Responsibility
  51. 51. A Good API Depends Upon Abstractions
  52. 52. And That’s SOLID Code
  53. 53. S - Single Responsibility Principle O- L - I - D- A Good API Does One Thing
  54. 54. S - Single Responsibility Principle O- Open / Closed Principle L - I - D- A Good API Never Changes
  55. 55. S - Single Responsibility Principle O- Open / Closed Principle L - Liskov Substitution Principle I - D- A Good API Behaves Like Its Contract
  56. 56. S - Single Responsibility Principle O- Open / Closed Principle L - Liskov Substitution Principle I - Interface Segregation Principle D- A Good API Has A Narrow Responsibility
  57. 57. 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
  58. 58. S - Single Responsibility Principle O- Open / Closed Principle L - Liskov Substitution Principle I - Interface Segregation Principle D- Dependency Inversion Principle
  59. 59. Note That SOLID Does Not Dictate What Is Good OOP
  60. 60. SOLID Emerges From Good OOP
  61. 61. So, What Makes A Bad API?
  62. 62. Global Variables (Spooky Action At A Distance)
  63. 63. Depending On Specifics Of An Implementation
  64. 64. Hidden Dependencies
  65. 65. Unhealthy Focus On Performance
  66. 66. Poorly Named APIs
  67. 67. Duplication
  68. 68. And That’s STUPID Code
  69. 69. S - Singletons T - U - P - I - D- Global Variables (Spooky Action At A Distance)
  70. 70. S - Singletons T - Tight Coupling U - P - I - D- Depending On Specifics Of An Implementation
  71. 71. S - Singletons T - Tight Coupling U - Untestable Code P - I - D- Hidden Dependencies
  72. 72. S - Singletons T - Tight Coupling U - Untestable Code P - Premature Optimization I - D- Unhealthy Focus On Performance
  73. 73. S - Singletons T - Tight Coupling U - Untestable Code P - Premature Optimization I - Indescriptive Naming D- Poorly Named APIs
  74. 74. S - Singletons T - Tight Coupling U - Untestable Code P - Premature Optimization I - Indescriptive Naming D- Duplication Duplication Duplication DuplicationDuplication Duplication Duplication Duplication Duplication
  75. 75. S - Singletons T - Tight Coupling U - Untestable Code P - Premature Optimization I - Indescriptive Naming D- Duplication
  76. 76. STUPID Embodies Lessons Learned From Bad OOP
  77. 77. 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)
  78. 78. 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
  79. 79. Let’s Look At Some Code!
  80. 80. interface Car { public function turnLeft(); public function turnRight(); public function goFaster(); public function goSlower(); public function shiftUp(); public function shiftDown(); public function start(); }
  81. 81. interface Steerable { public function steer($angle); } interface Acceleratable { public function accelerate($amt); } interface Shiftable { public function shiftDown(); public function shiftUp(); }
  82. 82. Let’s Look At Drupal Code!
  83. 83. interface MailSystemInterface { public function format(array $message); public function mail(array $message); }
  84. 84. interface MailSystemInterface { public function format(array $message); public function mail(array $message); } What Responsibility?
  85. 85. interface MailSystemInterface { public function format(array $message); public function mail(array $message); } What Responsibility? Formatting Messages
  86. 86. interface MailSystemInterface { public function format(array $message); public function mail(array $message); } What Responsibility? Formatting Messages Encoding Messages
  87. 87. interface MailSystemInterface { public function format(array $message); public function mail(array $message); } What Responsibility? Formatting Messages Encoding Messages Assembling Headers
  88. 88. interface MailSystemInterface { public function format(array $message); public function mail(array $message); } What Responsibility? Formatting Messages Encoding Messages Assembling Headers Calling Sendmail
  89. 89. 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…?
  90. 90. interface MailSystemInterface { public function format(array $message); public function mail(array $message); } What Responsibility? Open For Extension?
  91. 91. interface MailSystemInterface { public function format(array $message); public function mail(array $message); } What Responsibility? Open For Extension? Edits Require Copy/Paste
  92. 92. interface MailSystemInterface { public function format(array $message); public function mail(array $message); } What Responsibility? Open For Extension? Liskov Substitution...
  93. 93. interface MailSystemInterface { public function format(array $message); public function mail(array $message); } What Responsibility? Open For Extension? Liskov Substitution... One Interface... Many Responsibilites
  94. 94. interface MailSystemInterface { public function format(array $message); public function mail(array $message); } What Responsibility? Open For Extension? Liskov Substitution... One Interface... What Dependencies?
  95. 95. interface MessageFormatter { public function format(Message $message); } interface MessageEncoder { public function encode(Message $message); } interface MessageTransport { public function send(Message $message); }
  96. 96. class MailSystem { public function __construct( MessageFormatter $messageFormatter, MessageEncoder $messageEncoder, MessageTransport $messageTransport ) {} public function mail(Message $message); }
  97. 97. Principle Of Good Enough
  98. 98. Know the rules well so you can break them effectively... Dalai Lama XIV
  99. 99. Anthony Ferrara @ircmaxell blog.ircmaxell.com me@ircmaxell.com youtube.com/ircmaxell
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×