don't be stupid, grasp solid - confoo edition

Post on 18-May-2015

1.113 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

DESCRIPTION

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

TRANSCRIPT

Don’t Be STUPIDGrasp SOLID!

Anthony Ferrara

Let’s TalkObject

OrientedProgramming

WhatIs 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 A Button To Make It Roar?

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”?

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?

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

function equals(Number $n); function isLessThan(Number $n); function isGreaterThan(Number $n);

}

Number

IntegerFloat Decimal

longshort long long

unsigned signed

But Wait!

We Don’t Even Need Inheritance

All We Need IsPolymorphism

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->getValue() + 1.0);} elseif ($a->isDecimal()) { return new Decimal($a->getValue() + 1.0);

}

Polymorphic Code

return $number->add(new Integer(1));

Polymorphic Code

class Integer implements Number { public function add(Number $a) { return new Integer( $this->getValue() + (int) $a->getValue() ); }}

Polymorphic Code

class Float implements Number { public function add(Number $a) { return new Float( $this->getValue() + (float) $a->getValue() ); }}

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 Codeclass Decimal implements Number { protected $intValue; protected $exponent; public function equals(Number $a) { if ($a instanceof Decimal) { // Compare Directly } else { // Cast } }}

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 APIDoes One Thing

A Good APINever Changes

A Good APIBehaves Like Its

Contract

A Good APIHas A Narrow Responsibility

A Good APIDepends Upon Abstractions

And That’sSOLIDCode

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 Like Its Contract

S - Single Responsibility Principle O- Open / Closed Principle

L - Liskov Substitution Principle

I - Interface Segregation Principle

D-

A Good API Has A Narrow Responsibility

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

S - Single Responsibility Principle O- Open / Closed Principle

L - Liskov Substitution Principle

I - Interface Segregation Principle

D- Dependency Inversion Principle

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 OnSpecifics Of An Implementation

Hidden Dependencies

Unhealthy Focus On Performance

Poorly Named APIs

Duplication

And That’sSTUPID

Code

S - Singletons

T -U -P -I -D-

Global Variables(Spooky ActionAt 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 APIs

S - Singletons

T - Tight Coupling

U - Untestable Code

P - Premature Optimization

I - Indescriptive Naming

D- Duplication

Duplication

Duplication

DuplicationDuplication

Duplication

DuplicationDuplication

Duplication

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 CodeReusable CodeExtendable CodeEasy To Read CodeMaintainable CodeEasy To Change CodeEasy To Understand CodeClean Abstractions (mostly)

What Good OOP Costs You

Tends To Have More “Layers”Tends To Be Slower At RuntimeTends To Have Larger CodebasesTends To Result In Over-AbstractionTends To Require More Effort To WriteTends To Require More Tacit Knowledge

Let’s Look At Some Code!

interface Car {

public function turnLeft(); public function turnRight(); public function goFaster(); public function goSlower(); public function shiftUp(); public function shiftDown(); public function start();

}

interface Steerable { public function steer($angle);}interface Acceleratable { public function accelerate($amt);}interface Shiftable { public function shiftDown(); public function shiftUp();}

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 Responsibility?

interface MailSystemInterface {

public function format(array $message);

public function mail(array $message);

}

What Responsibility?

Formatting Messages

interface MailSystemInterface {

public function format(array $message);

public function mail(array $message);

}

What Responsibility?

Formatting Messages

Encoding Messages

interface MailSystemInterface {

public function format(array $message);

public function mail(array $message);

}

What Responsibility?

Formatting Messages

Encoding Messages

Assembling Headers

interface MailSystemInterface {

public function format(array $message);

public function mail(array $message);

}

What Responsibility?

Formatting Messages

Encoding Messages

Assembling Headers

Calling Sendmail

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…?

interface MailSystemInterface {

public function format(array $message);

public function mail(array $message);

}

What Responsibility?

Open For Extension?

interface MailSystemInterface {

public function format(array $message);

public function mail(array $message);

}

What Responsibility?

Open For Extension?

Edits Require Copy/Paste

interface MailSystemInterface {

public function format(array $message);

public function mail(array $message);

}

What Responsibility?

Open For Extension?

Liskov Substitution...

interface MailSystemInterface {

public function format(array $message);

public function mail(array $message);

}

What Responsibility?

Open For Extension?

Liskov Substitution...

One Interface...

Many Responsibilites

interface MailSystemInterface {

public function format(array $message);

public function mail(array $message);

}

What Responsibility?

Open For Extension?

Liskov Substitution...

One Interface...

What Dependencies?

interface MessageFormatter { public function format(Message $message);

}interface MessageEncoder { public function encode(Message $message);

}interface MessageTransport { public function send(Message $message);

}

class MailSystem { public function __construct( MessageFormatter $messageFormatter, MessageEncoder $messageEncoder, MessageTransport $messageTransport

) {} public function mail(Message $message);

}

Principle Of

GoodEnough

Know the rules wellso you can break them

effectively...Dalai Lama XIV

Anthony Ferrara@ircmaxell

blog.ircmaxell.comme@ircmaxell.comyoutube.com/ircmaxell

top related