solid: good object oriented design
DESCRIPTION
"SOLID" is an acronym for a set of principles to be used with Object Oriented programming, and that assist Developer in Good Software Design in order better reuse of classes and modules, application of unit tests and maintenance of Software.TRANSCRIPT
![Page 1: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/1.jpg)
Mario Rezende
http://about.me/mariorez
SOLIDGood Object Oriented Design
![Page 2: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/2.jpg)
Agenda
❖ Good OO Design
❖ The principles of SOLID
❖ Where SOLID “fits”
❖ The Principles by examples
❖ Bonus: Robert Martin & Books
![Page 3: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/3.jpg)
Good OO Design
Change , Dependency , Coupling
1. Changing Requirements
2. Dependency Management
![Page 4: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/4.jpg)
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 }}
Good OO Design
Change , Dependency , Coupling
![Page 5: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/5.jpg)
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 }}
Good OO Design
Change , Dependency , Coupling
![Page 6: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/6.jpg)
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 }}
Good OO Design
Change , Dependency , Coupling
![Page 7: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/7.jpg)
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 }}
Good OO Design
Change , Dependency , Coupling
![Page 8: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/8.jpg)
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 }}
what will be the result of this test
?
Good OO Design
Change , Dependency , Coupling
![Page 9: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/9.jpg)
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($stub); $this->assertEquals(1, $class->myMethod()); }}
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 }}
Good OO Design
Change , Dependency , Coupling
![Page 10: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/10.jpg)
Manifesto for AGILE Software Development
Individuals and interactionsWorking software
Customer collaboration
Responding to change
Good OO Design
Change , Dependency , Coupling, Agile
![Page 11: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/11.jpg)
S ingle Responsibility
Open / Closed
L iskov Substitution
I nterface Segregation
Dependency Inversion
The principles of SOLID
Change , Dependency , Coupling, Agile
![Page 12: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/12.jpg)
Object Oriented Principles
AbstractionEncapsulationInheritanceCompositionModularityPolymorphism
Principles of Class Design
Design Patterns
Layered Architecture
CohesionLow CouplingOrthogonalityDesign by ContractLaw of Demeter
MVCDDD
Frameworks
General SolutionRecurring problemsProgram to InterfaceFavor Composition
GranularityStabilityMetrics forstability and abstraction
implementation conceptual
Principles of Package and Component Design
Where SOLID “fits”
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 13: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/13.jpg)
Object Oriented Principles
AbstractionEncapsulationInheritanceCompositionModularityPolymorphism
Principles of Class Design
Design Patterns
Layered Architecture
CohesionLow CouplingOrthogonalityDesign by ContractLaw of Demeter
MVCDDD
Frameworks
General SolutionRecurring problemsProgram to InterfaceFavor Composition
GranularityStabilityMetrics forstability and abstraction
implementation conceptual
Principles of Package and Component Design
Where SOLID “fits”
Change , Dependency , Coupling, Agile , Composition , Interface
SOLID
![Page 14: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/14.jpg)
The Principles by examples S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
Single ResponsibilityA class should have only a single responsibility
(only one reason to change)
![Page 15: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/15.jpg)
Single Responsibility1234567891011121314151617181920
class Customer{ public function authenticate() { // authenticate user against a database }
public function authorize() { // 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->authorize()) { return true; } return false; }}
S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 16: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/16.jpg)
1234567891011121314
class AccessControlManager{ public function __construct(Customer $customer, Login $login) { //save references }
public function login() { if ($this->login->authenticate($this->customer) && $this->login->authorize($this->customer)) { return true; } return false; }}
Single Responsibility12345678910
class Customer{ public function setEmail($email) {}
public function getEmail() {}
public function setPassword($password) {}
public function getPassword() {}}
123456789101112
class Login{ public function authenticate(Customer $customer) { // authenticate user against a database }
public function authorize(Customer $customer) { // checks user privileges }}
S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 17: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/17.jpg)
Single Responsibility12345678910
class Customer{ public function setEmail($email) {}
public function getEmail() {}
public function setPassword($password) {}
public function getPassword() {}}
1234567
class SignIn{ public function authenticate(Customer $customer) { // authenticate user against a database }}
1234567
class Permission{ public function authorize(Customer $customer) { // checks user privileges }}
12345678910111213
class AccessControlManager { public function __construct(Customer $customer, SignIn $sign, Permission $perm) { //save references }
public function login() { if ($this->sign->authenticate($this->customer) && $this->perm->authorize($this->customer)) { return true; } return false; }}
S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 18: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/18.jpg)
Single Responsibility S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
Conclusion❖ SRP is the simplest, and the most difficult to get right
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)
![Page 19: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/19.jpg)
S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
The Principles by examples
Open / ClosedSoftware entities (classes, modules, functions, etc.)
should be open for extension, but closed for modification
![Page 20: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/20.jpg)
12345678910
class Customer{ public function setEmail($email) {}
public function getEmail() {}
public function setPassword($password) {}
public function getPassword() {}}
Open / Closed
1234567
class SignIn{ public function authenticate(Customer $customer) { // authenticate user against a database }}
1234567
class Permission{ public function authorize(Customer $customer) { // checks user privileges }}
12345678910111213
class AccessControlManager { public function __construct(Customer $customer, SignIn $sign, Permission $perm) { //save references }
public function login() { if ($this->sign->authenticate($this->customer) && $this->perm->authorize($this->customer)) { return true; } return false; }}
S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 21: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/21.jpg)
12345678910
class Customer{ public function setEmail($email) {}
public function getEmail() {}
public function setPassword($password) {}
public function getPassword() {}}
Open / Closed
1234567
class SignIn{ public function authenticate(Customer $customer) { // authenticate user against a database }}
1234567
class SignFacebook extends SignIn x{ public function authenticate(Customer $customer) { // connect to third-party server resource }}
12345678910111213
class AccessControlManager { public function __construct(Customer $customer, SignIn $sign, Permission $perm) { //save references }
public function login() { if ($this->sign->authenticate($this->customer) && $this->perm->authorize($this->customer)) { return true; } return false; }}
S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 22: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/22.jpg)
Open / Closed12345678910
class Customer{ public function setEmail($email) {}
public function getEmail() {}
public function setPassword($password) {}
public function getPassword() {}}
1234567
class SignIn { public function authenticate(Customer $customer) { // authenticate user against a database }
protected function getRepository(Adapter $db) x { // connect to database }}
1234567
class SignFacebook extends SignIn { public function authenticate(Customer $customer) { // connect to third-party server resource }
protected function getAccessToken(Oauth $client) { // retrieve a valid token }}
12345678910111213
class AccessControlManager { public function __construct(Customer $customer, SignIn $sign, Permission $perm) { //save references }
public function login() { if ($this->sign->authenticate($this->customer) && $this->perm->authorize($this->customer)) { return true; } return false; }}
S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 23: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/23.jpg)
Open / Closed12345678910
class Customer{ public function setEmail($email) {}
public function getEmail() {}
public function setPassword($password) {}
public function getPassword() {}}
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 { public function authenticate(Customer $customer);}
12345678910111213
class AccessControlManager { public function __construct(Customer $customer, SignService $sign, Permission $perm) { //save references }
public function login() { if ($this->sign->authenticate($this->customer) && $this->perm->authorize($this->customer)) { return true; } return false; }}
S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 24: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/24.jpg)
Open / Closed S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
Conclusion❖ OCP is at the heart of object-oriented design
❖ Flexibility, Reusability and Maintainability
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)
![Page 25: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/25.jpg)
S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
The Principles by examples
Dependency Inversion A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
B. Abstractions should not depend upon details. Details should depend upon abstractions.
![Page 26: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/26.jpg)
Dependency Inversion12345678910
class Customer{ public function setEmail($email) {}
public function getEmail() {}
public function setPassword($password) {}
public function getPassword() {}}
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 Permission{ public function authorize(Customer $customer) { // checks user privileges }}
12345678910111213
class AccessControlManager { public function __construct(Customer $customer, SignService $sign, Permission $perm) { //save references }
public function login() { if ($this->sign->authenticate($this->customer) && $this->perm->authorize($this->customer)) { return true; } return false; }}
S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 27: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/27.jpg)
Dependency Inversion S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 28: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/28.jpg)
Dependency Inversion
A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 29: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/29.jpg)
Dependency InversionPolicy
Mechanism
S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
![Page 30: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/30.jpg)
Dependency InversionPolicy
Mechanism
S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
![Page 31: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/31.jpg)
Dependency Inversion
12345678910
class Customer implements UserIdentity{ 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
class Permission implements GrantService { public function authorize(Customer $customer) { // checks user privileges }}
12345678910111213
class AccessControlManager { public function __construct(UserIdentity $user, SignService $sign, GrantService $grant) { //save references }
public function login() { if ($this->sign->authenticate($this->user) && $this->grant->authorize($this->user)) { return true; } return false; }}
1234
interface SignService{ public function authenticate(Customer $customer);}
1234
interface GrantService{ public function authorize(Customer $customer);}
1 interface UserIdentity { }
S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 32: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/32.jpg)
Dependency Inversion
12345678910
class Customer implements UserIdentity{ public function setEmail($email) {}
public function getEmail() {}
public function setPassword($password) {}
public function getPassword() {}}
1234
class SignDatabase implements SignService { public function authenticate(UserIdentity $user) { // authenticate user against a database }}
1234
class Permission implements GrantService { public function authorize(UserIdentity $user) { // checks user privileges }}
12345678910111213
class AccessControlManager { public function __construct(UserIdentity $user, SignService $sign, GrantService $grant) { //save references }
public function login() { if ($this->sign->authenticate($this->user) && $this->grant->authorize($this->user)) { return true; } return false; }}
1234
interface SignService{ public function authenticate(UserIdentity $user);}
1234
interface GrantService{ public function authorize(UserIdentity $user);}
1 interface UserIdentity { }
S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 33: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/33.jpg)
Dependency Inversion
B. Abstractions should not depend upon details. Details should depend upon abstractions.
S.O.L.I.DPolicy
Mechanism
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 34: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/34.jpg)
12345678910111213
class AccessControlManager { public function __construct(Customer $customer, SignIn $sign, Permission $perm) { //save references }
public function login() { if ($this->sign->authenticate($this->customer) && $this->perm->authorize($this->customer)) { return true; } return false; }}
Dependency Inversion12345678910
class Customer{ public function setEmail($email) {}
public function getEmail() {}
public function setPassword($password) {}
public function getPassword() {}}
1234567
class SignIn { public function authenticate(Customer $customer) { // authenticate user against a database }
protected function getRepository(Adapter $db) { // connect to database }}
1234567
class Permission{ public function authorize(Customer $customer) { // checks user privileges }}
S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 35: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/35.jpg)
Dependency Inversion
1234567
class SignDatabase implements SignService { public function authenticate(UserIdentity $user) { // authenticate user against a database }
protected function getRepository(Adapter $db) { // connect to database }}
12345678910
class Customer implements UserIdentity{ public function setEmail($email) {}
public function getEmail() {}
public function setPassword($password) {}
public function getPassword() {}}
1 interface UserIdentity { }
1234
interface SignService { public function authenticate(UserIdentity $user); protected function getRepository(Adapter $db);}
12345678910111213
class AccessControlManager { public function __construct(UserIdentity $user, SignService $sign, GrantService $grant) { //save references }
public function login() { if ($this->sign->authenticate($this->user) && $this->grant->authorize($this->user)) { return true; } return false; }}
1234
class Permission implements GrantService { public function authorize(UserIdentity $user) { // checks user privileges }}
1234
interface GrantService{ public function authorize(UserIdentity $user);}
S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 36: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/36.jpg)
Dependency Inversion
12345678910
class Customer implements UserIdentity{ public function setEmail($email) {}
public function getEmail() {}
public function setPassword($password) {}
public function getPassword() {}}
1 interface UserIdentity { }
1234567
class SignFacebook implements SignService { public function authenticate(UserIdentity $user) { // connect to third-party server resource }
protected function getAccessToken(Oauth $client) { // retrieve a valid token }}
12345678910111213
class AccessControlManager { public function __construct(UserIdentity $user, SignService $sign, GrantService $grant) { //save references }
public function login() { if ($this->sign->authenticate($this->user) && $this->grant->authorize($this->user)) { return true; } return false; }}
1234567
class SignDatabase implements SignService { public function authenticate(UserIdentity $user) { // authenticate user against a database }
protected function getRepository(Adapter $db) x { // connect to database }}
1234
interface SignService { public function authenticate(UserIdentity $user); protected function getRepository(Adapter $db); x}
S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 37: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/37.jpg)
Dependency Inversion
12345678910
class Customer implements UserIdentity{ public function setEmail($email) {}
public function getEmail() {}
public function setPassword($password) {}
public function getPassword() {}}
1 interface UserIdentity { }
1234567
class SignFacebook implements SignService { public function authenticate(UserIdentity $user) { // connect to third-party server resource }
protected function getAccessToken(Oauth $client) { // retrieve a valid token }}
12345678910111213
class AccessControlManager { public function __construct(UserIdentity $user, SignService $sign, GrantService $grant) { //save references }
public function login() { if ($this->sign->authenticate($this->user) && $this->grant->authorize($this->user)) { return true; } return false; }}
1234567
class SignDatabase implements SignService { public function authenticate(UserIdentity $user) { // authenticate user against a database }
protected function getRepository(Adapter $db) { // connect to database }}
1234
interface SignService{ public function authenticate(UserIdentity $user);}
S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 38: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/38.jpg)
Dependency Inversion S.O.L.I.DPolicy
Mechanism
Change , Dependency , Coupling, Agile , Composition , Interface
B. Abstractions should not depend upon details. Details should depend upon abstractions.
![Page 39: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/39.jpg)
Dependency InversionPolicy
Utility
Mechanism
S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 40: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/40.jpg)
Dependency Inversion S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
Conclusion❖ Rules and details should depend on abstractions,
which are defined in terms of use
❖ When abstractions and details are isolated,it's easier to maintain the code
... inversion of dependencies is the hallmark of good object-oriented design.(Robert Martin)
![Page 41: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/41.jpg)
S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
The Principles by examples
Liskov SubstitutionObjects in a program should be replaceable
with instances of their subtypes without alteringthe correctness of that program
![Page 42: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/42.jpg)
Liskov Substitution
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'); }}
S.O.L.I.D1234567
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 }}
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 43: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/43.jpg)
Liskov Substitution
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'); }}
S.O.L.I.D1234567
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 }}
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 44: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/44.jpg)
Liskov Substitution S.O.L.I.D1234567
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 }}
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 45: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/45.jpg)
Liskov Substitution S.O.L.I.D1234567
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 }}
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 46: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/46.jpg)
Liskov Substitution
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 }}
S.O.L.I.D1234567
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 }}
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 47: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/47.jpg)
Liskov Substitution
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 }}
S.O.L.I.D
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 }
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 48: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/48.jpg)
Liskov Substitution
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 }}
S.O.L.I.D
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 }
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 49: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/49.jpg)
Liskov Substitution S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
Conclusion❖ LSP is one of the prime enablers of OCP
❖ Design by Contract (require no more, promise no less)
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)
![Page 50: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/50.jpg)
S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
The Principles by examples
Interface SegregationMany client-specific interfaces are better than
one general-purpose interface
![Page 51: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/51.jpg)
Interface Segregation S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
AtmUI+ requestDeposit+ requestWithdrawl+ requestTransfer+ informeInsufficientFunds
![Page 52: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/52.jpg)
Interface Segregation S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
AtmUI+ requestDeposit+ requestWithdrawl+ requestTransfer+ informeInsufficientFunds
![Page 53: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/53.jpg)
Interface Segregation S.O.L.I.D
Change , Dependency , Coupling, Agile , Composition , Interface
Conclusion❖ Avoids the use of "Fat Classes"
❖ Breaks the dependence of the clients on methods that they don't invoke
❖ Allows the clients to be independent of one another
![Page 54: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/54.jpg)
?Change , Dependency , Coupling, Agile , Composition , Interface
Questions
![Page 55: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/55.jpg)
Robert Martin
S ingle responsibility
Open/closed
L iskov substitution
I nterface segregation
Dependency inversion
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 56: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/56.jpg)
Robert Martin
SOLID
Change , Dependency , Coupling, Agile , Composition , Interface
![Page 57: Solid: Good Object Oriented Design](https://reader034.vdocuments.us/reader034/viewer/2022052522/554a0638b4c905e56c8b5673/html5/thumbnails/57.jpg)
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 (Martin Fowler - 2002)Apps para Android
Change , Dependency , Coupling, Agile , Composition , Interface
Recommended Books