solid: bom design em orientação a objetos

58
Trilha PHP – SOLID Bom Design em Orientação a Objetos Mario Rezende Desenvolvedor PHP na Kanui.com.br Integrante do Grupo de Usuários PHPSP.org.br

Upload: mario-rezende

Post on 13-Jun-2015

2.965 views

Category:

Technology


3 download

DESCRIPTION

"SOLID" é um acrônimo para um conjunto de princípios a serem utilizados com Orientação a Objetos, e que auxiliam o Desenvolvedor no bom Design de Software tendo em vista melhor reutilização de Classes e Módulos, aplicação de testes unitários e manutenção do Software.

TRANSCRIPT

Page 1: SOLID:  Bom Design em Orientação a Objetos

Trilha PHP – SOLIDBom Design em Orientação a Objetos

Mario RezendeDesenvolvedor PHP na Kanui.com.br

Integrante do Grupo de Usuários PHPSP.org.br

Page 2: SOLID:  Bom Design em Orientação a Objetos

❖ Bom Design em OO

❖ Os Princípios do SOLID

❖ Onde o SOLID se “encaixa”

❖ Exemplos de Código

❖ Bônus: Robert Martin & Livros

Agenda

Page 3: SOLID:  Bom Design em Orientação a Objetos

Bom Design em OO

Mudança , Dependência , Acoplamento

1. Mudança de Requisitos

2. Gestão de Dependências

Page 4: SOLID:  Bom Design em Orientação a Objetos

Bom Design em OO

12345678910

1234

class AnotherClass{ public function doSomething() { // logic }}

12345678910

class Controller{ public function action() { $myClass = new MyClass(); $result = $myClass->myMethod();

$this->render($result); }}

class MyClass{ public function myMethod() { $otherClass = new AnotherClass(); x $anyThing = $otherClass->doSomething();

// solves some logic and returns the result }}

Mudança , Dependência , Acoplamento

Page 5: SOLID:  Bom Design em Orientação a Objetos

Bom Design em OO

Mudança , Dependência , Acoplamento

1234

class AnotherClass{ public function doSomething() { // logic }}

1 class ClassA { // depends AnotherClass }

1 class ClassB { // depends AnotherClass }

12345678910

12345678910

class Controller{ public function action() { $myClass = new MyClass(); $result = $myClass->myMethod();

$this->render($result); }}

class MyClass{ public function myMethod() { $otherClass = new AnotherClass(); x $anyThing = $otherClass->doSomething();

// solves some logic and returns the result }}

Page 6: SOLID:  Bom Design em Orientação a Objetos

Bom Design em OO

Mudança , Dependência , Acoplamento

123456789

1234

class AnotherClass{ public function doSomething() { // logic }}

1234567891011

1 class ClassA { // depends AnotherClass }

1 class ClassB { // depends AnotherClass }

class Controller{ public function action() { $myClass = new MyClass(); $otherClass = new AnotherClass();xxx xxxxxx $result = $myClass->myMethod($otherClass);

$this->render($result); }}

class MyClass{ public function myMethod(AnotherClass $class) { $anyThing = $class->doSomething();

// solves some logic and returns the result }}

Page 7: SOLID:  Bom Design em Orientação a Objetos

Bom Design em OO

Mudança , Dependência , Acoplamento

123456789

1234

class AnotherClass{ public function doSomething() { // logic }}

1234567891011

1 class ClassA { // depends AnotherClass }

1 class ClassB { // depends AnotherClass }

class Controller{ public function action() { $myClass = new MyClass(); $otherClass = new DerivedClass();xxxxxx xxx $result = $myClass->myMethod($otherClass);

$this->render($result); }}

class MyClass{ public function myMethod(AnotherClass $class) { $anyThing = $class->doSomething();

// solves some logic and returns the result }}

1234

class DerivedClass extends AnotherClass x{ public function doSomething() { // logic }}

Page 8: SOLID:  Bom Design em Orientação a Objetos

Bom Design em OO

Mudança , Dependência , Acoplamento

12345678910

12345678

class MyClassTest extends PHPUnit_Framework_TestCase{ public function testMyMethod() { $class = new MyClass(); $this->assertEquals(1, $class->myMethod()); }}

1234

class MyClass{ public function myMethod() { $otherClass = new AnotherClass(); x $anyThing = $otherClass->doSomething();

// solves some logic and returns the result }}

class AnotherClass{ public function doSomething() { // logic }}

Este teste irá passar

?

Page 9: SOLID:  Bom Design em Orientação a Objetos

Bom Design em OO

Mudança , Dependência , Acoplamento

12345678910111213141516

class MyClassTest extends PHPUnit_Framework_TestCase{ public function testMyMethod() { // Create a stub for the AnotherClass class. $stub = $this->getMock('AnotherClass'); x

// Configure the stub. $stub->expects($this->any()) ->method('doSomething') ->will($this->returnValue('mon')); x

$class = new MyClass(); $this->assertEquals(1, $class->myMethod($stub)); }}

123456789

class MyClass{ public function myMethod(AnotherClass $class) { $anyThing = $class->doSomething();

// solves some logic and returns the result }}

1234

class AnotherClass{ public function doSomething() { // logic }}

Page 10: SOLID:  Bom Design em Orientação a Objetos

Bom Design em OO

Manifesto para Desenvolvimento

ÁGIL de Software

Mudança , Dependência , Acoplamento , Ágil

Indivíduos e interaçõesSoftware em funcionamento

Colaboração com o cliente

Responder a Mudanças

Page 11: SOLID:  Bom Design em Orientação a Objetos

Os Princípios do SOLID

S ingle Responsibility

Open / Closed

L iskov Substitution

I nterface Segregation

Dependency Inversion

Mudança , Dependência , Acoplamento , Ágil

Page 12: SOLID:  Bom Design em Orientação a Objetos

Princípios Orientação Objetos

AbstraçãoEncapsulamentoHerançaComposiçãoModularidadePolimorfismo

Princípios de Design de Classe

Padrões de Design

Arquitetura em Camadas

Arquitetura Distribuída

SOAESB

SaaS

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

implementação conceitual

Coesão< AcoplamentoOrtogonalidadeDesign p/ ContratoLei de Deméter

MVCDDDFrameworks

Solução GenéricaProblemas RecorrentesPrograme p/ InterfacePrefira Composição

Onde o SOLID se “encaixa”

Page 13: SOLID:  Bom Design em Orientação a Objetos

Princípios Orientação Objetos

AbstraçãoEncapsulamentoHerançaComposiçãoModularidadePolimorfismo

Princípios de Design de Classe

Padrões de Design

Arquitetura em Camadas

Arquitetura Distribuída

SOAESB

SaaS

Coesão< AcoplamentoOrtogonalidadeDesign p/ ContratoLei de Deméter

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

SOLID

implementação conceitual

MVCDDDFrameworks

Solução GenéricaProblemas RecorrentesPrograme p/ InterfacePrefira Composição

Onde o SOLID se “encaixa”

Page 14: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Single ResponsibilityUma Classe deve ter uma única razão para mudar

(responsabilidade única)

Exemplos de Código S.O.L.I.D

Page 15: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Single Responsibility1234567891011121314151617181920

class Customer{ public function authenticate() { // authenticate user in a database }

public function hasRole($role) { // checks user privileges }

public function setEmail($email) {}

public function getEmail() {}

public function setPassword($password) {}

public function getPassword() {}}

1234567891011121314

class AccessControlManager{ public function __construct(Customer $customer) { //save reference }

public function login() { if ($this->customer->authenticate() && $this->customer->hasRole('user')) { return true; }

return false; }}

S.O.L.I.D

Page 16: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Single Responsibility1234567891011121314

class AccessControlManager{ public function __construct(Customer $customer, Security $secur) { //save references }

public function login() { if ($this->secur->authenticate($this->customer) && $this->secur->hasRole('user', $this->customer)) { return true; }

return false; }}

12345678910

class Customer{ public function setEmail($email) {}

public function getEmail() {}

public function setPassword($password) {}

public function getPassword() {}}

123456789101112

class Security{ public function authenticate(Customer $customer) { // authenticate user in a database }

public function hasRole($role, Customer $customer) { // checks user privileges }}

S.O.L.I.D

Page 17: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Single Responsibility12345678910

class Customer{ public function setEmail($email) {}

public function getEmail() {}

public function setPassword($password) {}

public function getPassword() {}}

1234567

class Sign{ public function authenticate(Customer $customer) { // authenticate user in a database }}

1234567

class Grant{ public function hasRole($role, Customer $customer) { // checks user privileges }}

1234567891011121314

class AccessControlManager{ public function __construct(Customer $customer, Sign $sign, Grant $grant) { //save references }

public function login() { if ($this->sign->authenticate($this->customer) && $this->grant->hasRole('user', $this->customer)) { return true; }

return false; }}

S.O.L.I.D

Page 18: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Conclusão❖ SRP é o mais simples, e o mais difícil de fazer certo

Finding and separating those responsibilities is much of whatsoftware design is really about. Indeed, the rest of the principles

we discuss come back to this issue in one way or another.(Robert Martin)

Single Responsibility S.O.L.I.D

Page 19: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Open / ClosedEntidades (classes, módulos, etc) devem ser

aberta para extensão, mas fechada para modificação

Exemplos de Código S.O.L.I.D

Page 20: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Open / Closed S.O.L.I.D12345678910

class Customer{ public function setEmail($email) {}

public function getEmail() {}

public function setPassword($password) {}

public function getPassword() {}}

1234567

class Sign{ public function authenticate(Customer $customer) { // authenticate user in a database }}

1234567

class Grant{ public function hasRole($role, Customer $customer) { // checks user privileges }}

1234567891011121314

class AccessControlManager{ public function __construct(Customer $customer, Sign $sign, Grant $grant) { //save references }

public function login() { if ($this->sign->authenticate($this->customer) && $this->grant->hasRole('user', $this->customer)) { return true; }

return false; }}

Page 21: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Open / Closed S.O.L.I.D12345678910

class Customer{ public function setEmail($email) {}

public function getEmail() {}

public function setPassword($password) {}

public function getPassword() {}}

1234567891011121314

class AccessControlManager{ public function __construct(Customer $customer, Sign $sign, Grant $grant) { //save references }

public function login() { if ($this->sign->authenticate($this->customer) && $this->grant->hasRole('user', $this->customer)) { return true; }

return false; }}

1234567

class Sign{ public function authenticate(Customer $customer) { // authenticate user in a database }}

1234567

class SignFacebook extends Sign x{ public function authenticate(Customer $customer) { // connect to third-party server resource }}

Page 22: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Open / Closed S.O.L.I.D12345678910

class Customer{ public function setEmail($email) {}

public function getEmail() {}

public function setPassword($password) {}

public function getPassword() {}}

1234567891011121314

class AccessControlManager{ public function __construct(Customer $customer, Sign $sign, Grant $grant) { //save references }

public function login() { if ($this->sign->authenticate($this->customer) && $this->grant->hasRole('user', $this->customer)) { return true; }

return false; }}

1234567

class Sign { public function authenticate(Customer $customer) { // authenticate user in a database }

protected function getRepository(Adapter $db) x { // connect to database }}

1234567

class SignFacebook extends Sign { public function authenticate(Customer $customer) { // connect to third-party server resource }

protected function getAccessToken(Oauth $client) { // retrieve a valid token }}

Page 23: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Open / Closed S.O.L.I.D12345678910

class Customer{ public function setEmail($email) {}

public function getEmail() {}

public function setPassword($password) {}

public function getPassword() {}}

12345678910111213

class AccessControlManager{ public function __construct(Customer $customer, SignService $sign, Grant $grant) { // references }

public function login() { if ($this->sign->authenticate($this->customer) && $this->grant->hasRole('user', $this->customer)) { return true; } return false; }}

1234567

class SignDatabase implements SignService { x public function authenticate(Customer $customer) { // authenticate user against a database }

protected function getRepository(Adapter $db) { // connect to database }}

1234567

class SignFacebook implements SignService { x public function authenticate(Customer $customer) { // connect to third-party server resource }

protected function getAccessToken(Oauth $client) { // retrieve a valid token }}

1234

interface SignService x { public function authenticate(Customer $customer);}

Page 24: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Conclusão❖ OCP está no coração do Design Orientado a Objetos

❖ Flexibilidade, Reutilização e Manutenibilidade

Nor is it a good idea to apply rampant abstractionto every part of the application…

Resisting premature abstraction is as important as abstraction itself.(Robert Martin)

Open / Closed S.O.L.I.D

Page 25: SOLID:  Bom Design em Orientação a Objetos

Dependency Inversion A. Módulos de Alto nível não devem depender de módulos de Baixo nível, ambos devem depender de Abstrações

B. Abstrações não devem depender de detalhes, Detalhes devem depender de Abstrações

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Exemplos de Código S.O.L.I.D

Page 26: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

S.O.L.I.D12345678910

class Customer{ public function setEmail($email) {}

public function getEmail() {}

public function setPassword($password) {}

public function getPassword() {}}

12345678910111213

class AccessControlManager{ public function __construct(Customer $customer, SignService $sign, Grant $grant) { // references }

public function login() { if ($this->sign->authenticate($this->customer) && $this->grant->hasRole('user', $this->customer)) { return true; } return false; }}

1234567

class SignDatabase implements SignService { public function authenticate(Customer $customer) { // authenticate user against a database }

protected function getRepository(Adapter $db) { // connect to database }}

1234

interface SignService{ public function authenticate(Customer $customer);}

1234567

class Grant{ public function hasRole($role, Customer $customer) { // checks user privileges }}

Dependency Inversion

Page 27: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Dependency Inversion S.O.L.I.D

Page 28: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

A. Módulos de Alto nível não devem depender de módulos de Baixo nível, ambos devem depender de Abstrações

Dependency Inversion S.O.L.I.D

Page 29: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Policy

Mechanism

A. Módulos de Alto nível não devem depender de módulos de Baixo nível, ambos devem depender de Abstrações

Dependency Inversion S.O.L.I.D

Page 30: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Policy

Mechanism

A. Módulos de Alto nível não devem depender de módulos de Baixo nível, ambos devem depender de Abstrações

Dependency Inversion S.O.L.I.D

Page 31: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

12345678910

class Customer implements User{ public function setEmail($email) {}

public function getEmail() {}

public function setPassword($password) {}

public function getPassword() {}}

1234

class SignDatabase implements SignService { public function authenticate(Customer $customer) { // authenticate user against a database }}

1234

interface SignService{ public function authenticate(Customer $customer);}

1234

interface GrantService{ public function hasRole($role, Customer $customer)}

1 interface User { // Getter & Setters }

Dependency Inversion S.O.L.I.D12345678910111213

class AccessControlManager{ public function __construct(User $user, SignService $sign, GrantService $grant) { // refs }

public function login() { if ($this->sign->authenticate($this->user) && $this->grant->hasRole('user', $this->user)) { return true; } return false; }}

1234

class BaseGrant implements GrantService { public function hasRole($role, Customer $customer) { // checks user privileges }}

Page 32: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

12345678910

class Customer implements User{ public function setEmail($email) {}

public function getEmail() {}

public function setPassword($password) {}

public function getPassword() {}}

1234

class SignDatabase implements SignService { public function authenticate(User $user) { // authenticate user against a database }}

1234

interface SignService{ public function authenticate(User $user);}

1234

interface GrantService{ public function hasRole($role, User $user);}

1 interface User { // Getter & Setters }

Dependency Inversion S.O.L.I.D12345678910111213

class AccessControlManager{ public function __construct(User $user, SignService $sign, GrantService $grant) { // refs }

public function login() { if ($this->sign->authenticate($this->user) && $this->grant->hasRole('user', $this->user)) { return true; } return false; }}

1234

class BaseGrant implements GrantService { public function hasRole($role, User $user) { // checks user privileges }}

Page 33: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

B. Abstrações não devem depender de detalhes, Detalhes devem depender de Abstrações

Policy

Mechanism

Dependency Inversion S.O.L.I.D

Page 34: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

12345678910

class Customer{ public function setEmail($email) {}

public function getEmail() {}

public function setPassword($password) {}

public function getPassword() {}}

1234567

class Sign{ public function authenticate(Customer $customer) { // authenticate user in a database }}

1234567

class Grant{ public function hasRole($role, Customer $customer) { // checks user privileges }}

1234567891011121314

class AccessControlManager{ public function __construct(Customer $customer, Sign $sign, Grant $grant) { //save references }

public function login() { if ($this->sign->authenticate($this->customer) && $this->grant->hasRole('user', $this->customer)) { return true; }

return false; }}

Dependency Inversion S.O.L.I.D

Page 35: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Dependency Inversion S.O.L.I.D

12345678910

class Customer implements User{ public function setEmail($email) {}

public function getEmail() {}

public function setPassword($password) {}

public function getPassword() {}}

1234

interface GrantService{ public function hasRole($role, User $user);}

1 interface User { // Getter & Setters }12345678910111213

class AccessControlManager{ public function __construct(User $user, SignService $sign, GrantService $grant) { // refs }

public function login() { if ($this->sign->authenticate($this->user) && $this->grant->hasRole('user', $this->user)) { return true; } return false; }}

1234

class BaseGrant implements GrantService { public function hasRole($role, User $user) { // checks user privileges }}

1234567

class SignDatabase implements SignService { public function authenticate(User $user) { // authenticate user against a database }

protected function getRepository(Adapter $db) { // connect to database }}

1234

interface SignService { public function authenticate(User $user); protected function getRepository(Adapter $db);}

Page 36: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Dependency Inversion S.O.L.I.D

12345678910

class Customer implements User{ public function setEmail($email) {}

public function getEmail() {}

public function setPassword($password) {}

public function getPassword() {}}

1 interface User { // Getter & Setters }12345678910111213

class AccessControlManager{ public function __construct(User $user, SignService $sign, GrantService $grant) { // refs }

public function login() { if ($this->sign->authenticate($this->user) && $this->grant->hasRole('user', $this->user)) { return true; } return false; }}

1234567

class SignDatabase implements SignService { public function authenticate(User $user) { // authenticate user against a database }

protected function getRepository(Adapter $db) { // connect to database }}

1234

interface SignService { public function authenticate(User $user); protected function getRepository(Adapter $db);}

1234567

class SignFacebook implements SignService { public function authenticate(User $user) { // connect to third-party server resource }

protected function getAccessToken(Oauth $client) { // retrieve a valid token }}

Page 37: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Dependency Inversion S.O.L.I.D

12345678910

class Customer implements User{ public function setEmail($email) {}

public function getEmail() {}

public function setPassword($password) {}

public function getPassword() {}}

1 interface User { // Getter & Setters }12345678910111213

class AccessControlManager{ public function __construct(User $user, SignService $sign, GrantService $grant) { // refs }

public function login() { if ($this->sign->authenticate($this->user) && $this->grant->hasRole('user', $this->user)) { return true; } return false; }}

1234567

class SignDatabase implements SignService { public function authenticate(User $user) { // authenticate user against a database }

protected function getRepository(Adapter $db) { // connect to database }}

1234

interface SignService{ public function authenticate(User $user);}

1234567

class SignFacebook implements SignService { public function authenticate(User $user) { // connect to third-party server resource }

protected function getAccessToken(Oauth $client) { // retrieve a valid token }}

Page 38: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

B. Abstrações não devem depender de detalhes, Detalhes devem depender de Abstrações

Policy

Mechanism

Dependency Inversion S.O.L.I.D

Page 39: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Policy

Utility

Mechanism

Dependency Inversion S.O.L.I.D

Page 40: SOLID:  Bom Design em Orientação a Objetos

Conclusão❖ Regras e detalhes devem depender de abstrações,

que são definidas do ponto de vista do uso

❖ Quando as abstrações e detalhes estão isolados, é mais fácil de dar manutenção no código

... inversion of dependencies is the hallmark of good object-oriented design.(Robert Martin)

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Dependency Inversion S.O.L.I.D

Page 41: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Liskov SubstitutionPossibilidade de Substituir a Classe Base pela sua Derivada,

sem alterar o funcionamento correto do Software

Exemplos de Código S.O.L.I.D

Page 42: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

1234567891011

class PaymentCalculator{ public function calculatePayday(Payment $pay) { $calendar = $this->getBrazilianCalendar(); $workDays = $this->getWorkDays($calendar); // calculate 5+ days: 2013-10-06 Sunday // find NEXT work day: 2013-10-07 Monday return new DateTime('2013-10-07'); }}

1234567

class Payment{ private $type; //CreditCard, Billet private $amount; private $createdAt; //2013-10-01 Tue private $payday;}

1234567891011

class PaymentManager{ public function __construct(Payment $payment, PaymentCalculator $calc) { // save references }

public function schedulePayment() { $payday = $this->calc->calculatePayday($this->payment); $this->payment->setPayday($payday); // save in database }}

Liskov Substitution S.O.L.I.D

Page 43: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

1234567891011

class PaymentCalculator{ public function calculatePayday(Payment $pay) { $calendar = $this->getBrazilianCalendar(); $workDays = $this->getWorkDays($calendar); // calculate 5+ days: 2013-10-06 Sunday // find NEXT work day: 2013-10-07 Monday return new DateTime('2013-10-07'); }}

1234567

class Payment{ private $type; //CreditCard, Billet private $amount; private $createdAt; //2013-10-01 Tue private $payday;}

1234567891011

class PaymentCalcBefore extends PaymentCalculator{ public function calculatePayday(Payment $pay) { $calendar = $this->getBrazilianCalendar(); $workDays = $this->getWorkDays($calendar); // calculate 5+ days: 2013-10-06 Sunday // find PREV work day: 2013-10-04 Friday return date('2013-10-04'); }}

1234567891011

class PaymentManager{ public function __construct(Payment $payment, PaymentCalculator $calc) { // save references }

public function schedulePayment() { $payday = $this->calc->calculatePayday($this->payment); $this->payment->setPayday($payday); // save in database }}

Liskov Substitution S.O.L.I.D

Page 44: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

1234567

class Payment{ private $type; //CreditCard, Billet private $amount; private $createdAt; //2013-10-01 Tue private $payday;}

123456789101112

class PaymentCalcBefore extends PaymentCalculator{ /** @return String */ x public function calculatePayday(Payment $pay) { $calendar = $this->getBrazilianCalendar(); $workDays = $this->getWorkDays($calendar); // calculate 5+ days: 2013-10-06 Sunday // find PREV work day: 2013-10-04 Friday return date('2013-10-04'); }}

123456789101112

class PaymentCalculator{ /** @return DateTime */ x public function calculatePayday(Payment $pay) { $calendar = $this->getBrazilianCalendar(); $workDays = $this->getWorkDays($calendar); // calculate 5+ days: 2013-10-06 Sunday // find NEXT work day: 2013-10-07 Monday return new DateTime('2013-10-07'); }}

1234567891011

class PaymentManager{ public function __construct(Payment $payment, PaymentCalculator $calc) { // save references }

public function schedulePayment() { $payday = $this->calc->calculatePayday($this->payment); $this->payment->setPayday($payday); // save in database }}

Liskov Substitution S.O.L.I.D

Page 45: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

1234567

class Payment{ private $type; //CreditCard, Billet private $amount; private $createdAt; //2013-10-01 Tue private $payday;}

123456789101112

class PaymentCalcBefore extends PaymentCalculator{ /** @return DateTime */ x public function calculatePayday(Payment $pay) { $calendar = $this->getBrazilianCalendar(); $workDays = $this->getWorkDays($calendar); // calculate 5+ days: 2013-10-06 Sunday // find PREV work day: 2013-10-04 Friday return new DateTime('2013-10-04'); }}

123456789101112

class PaymentCalculator{ /** @return DateTime */ x public function calculatePayday(Payment $pay) { $calendar = $this->getBrazilianCalendar(); $workDays = $this->getWorkDays($calendar); // calculate 5+ days: 2013-10-06 Sunday // find NEXT work day: 2013-10-07 Monday return new DateTime('2013-10-07'); }}

1234567891011

class PaymentManager{ public function __construct(Payment $payment, PaymentCalculator $calc) { // save references }

public function schedulePayment() { $payday = $this->calc->calculatePayday($this->payment); $this->payment->setPayday($payday); // save in database }}

Liskov Substitution S.O.L.I.D

Page 46: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

123456

class PaymentCalcBefore extends PaymentCalculator { protected function resolvePayDay($workDays,$pay) { // calculate D+5 and find PREVIOUS work day return new DateTime('2013-10-04'); // Friday }}

123456789101112

class PaymentCalculator { public function calculatePayday(Payment $pay) { $calendar = $this->getBrazilianCalendar(); $workDays = $this->getWorkDays($calendar); return $this->resolvePayDay($workDays, $pay); }

protected function resolvePayDay($workDays,$pay) { // calculate D+5 and find NEXT work day return new DateTime('2013-10-07'); // Monday }}

1234567

class Payment{ private $type; //CreditCard, Billet private $amount; private $createdAt; //2013-10-01 Tue private $payday;}

1234567891011

class PaymentManager{ public function __construct(Payment $payment, PaymentCalculator $calc) { // save references }

public function schedulePayment() { $payday = $this->calc->calculatePayday($this->payment); $this->payment->setPayday($payday); // save in database }}

Liskov Substitution S.O.L.I.D

Page 47: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

123456

class BeforeCalculator extends PaymentCalculator{ protected function resolvePayDay($workDays,$pay) { return new DateTime('2013-10-04'); // Friday }}

1234567891011

abstract class PaymentCalculator{ public function calculatePayday(Payment $pay) { $calendar = $this->getBrazilianCalendar(); $workDays = $this->getWorkDays($calendar); return $this->resolvePayDay($workDays,$payment); }

abstract protected function resolvePayDay($wd,$p);}

1234567891011

class PaymentManager{ public function __construct(Payment $payment, PaymentCalculator $calc) { // save references }

public function schedulePayment() { $payday = $this->calc->calculatePayday($this->payment); $this->payment->setPayday($payday); // save in database }}

123456

class AfterCalculator extends PaymentCalculator{ protected function resolvePayDay($workDays,$pay) { return new DateTime('2013-10-07'); // Monday }}

123

class CCardPayment implements Payment{ // attributes and methods }

1 interface Payment { }

123

class BilletPayment implements Payment { // attributes and methods }

Liskov Substitution S.O.L.I.D

Page 48: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

123456

class CreditCardCalculator extends PaymentCalculator{ protected function resolvePayDay($workDays,$pay) { return new DateTime('2013-10-04'); // Friday }}

1234567891011

abstract class PaymentCalculator{ public function calculatePayday(Payment $pay) { $calendar = $this->getBrazilianCalendar(); $workDays = $this->getWorkDays($calendar); return $this->resolvePayDay($workDays,$payment); }

abstract protected function resolvePayDay($wd,$p);}

1234567891011

class PaymentManager{ public function __construct(Payment $payment, PaymentCalculator $calc) { // save references }

public function schedulePayment() { $payday = $this->calc->calculatePayday($this->payment); $this->payment->setPayday($payday); // save in database }}

123456

class BilletCalculator extends PaymentCalculator{ protected function resolvePayDay($workDays,$pay) { return new DateTime('2013-10-07'); // Monday }}

1 interface Payment { }

123

class CCardPayment implements Payment{ // attributes and methods }

123

class BilletPayment implements Payment { // attributes and methods }

Liskov Substitution S.O.L.I.D

Page 49: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Conclusão❖ LSP é o principal facilitador do OPC

❖ Design by Contract (não peça demais, não prometa menos)

The term IS-A is too broad to act as a definition of a subtype.The true definition of a subtype is substitutable ...

(Robert Martin)

Liskov Substitution S.O.L.I.D

Page 50: SOLID:  Bom Design em Orientação a Objetos

Interface SegregationMuitas Interfaces específicas são melhores do que

uma Inferface de proposito geral

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Exemplos de Código S.O.L.I.D

Page 51: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

AtmUI+ requestDeposit+ requestWithdrawl+ requestTransfer+ informeInsufficientFunds

Interface Segregation S.O.L.I.D

Page 52: SOLID:  Bom Design em Orientação a Objetos

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

AtmUI+ requestDeposit+ requestWithdrawl+ requestTransfer+ informeInsufficientFunds

Interface Segregation S.O.L.I.D

Page 53: SOLID:  Bom Design em Orientação a Objetos

Conclusão❖ Evita a utilização de “Fat Classes”

❖ Quebra a dependência de métodos que não são invocados pelos clientes

❖ Permite a independência entre clientes

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Interface Segregation S.O.L.I.D

Page 54: SOLID:  Bom Design em Orientação a Objetos

?Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Dúvidas

Page 55: SOLID:  Bom Design em Orientação a Objetos

S ingle responsibility

Open/closed

L iskov substitution

I nterface segregation

Dependency inversion

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Robert Martin

Page 56: SOLID:  Bom Design em Orientação a Objetos

SOLID

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Robert Martin

Page 57: SOLID:  Bom Design em Orientação a Objetos

Agile Software Development, Principles, Patterns, and Practices (Robert Martin - 2002)Agile Principles, Patterns, and Practices in C# (Robert Martin - 2006) SOLID e Design Patterns

The Pragmatic Programmer (Andrew Hunt and Devid Thomas - 1999)Coesão, Acoplamento, Ortogonalidade, Design por Contrato, Lei de Deméter

Clean Code: A Handbook of Agile Software Craftsmanship (Robert C. Martin - 2008)Lei de Deméter, Data Transfer Objects, TDD

Domain-Driven Design: Tackling Complexity in the Heart of Software (Erich Evans - 2003)

Design Patterns: Elements of Reusable Object-Oriented Software (Gang of Four - 1994)Patterns of Enterprise Applications Architecture (PoeAA: Martin Fowler - 2002)

Apps para Android

Mudança , Dependência , Acoplamento , Ágil , Composição , Interface

Livros Recomendados

Page 58: SOLID:  Bom Design em Orientação a Objetos

VALEU !!!Mario Rezende

http://about.me/mariorez