architecture logicielle #3 : object oriented design

63
Architecture logicielle : Object-oriented design

Upload: jean-michel

Post on 15-Jul-2015

147 views

Category:

Software


3 download

TRANSCRIPT

Page 1: Architecture logicielle #3 : object oriented design

Architecture logicielle : Object-oriented design

Page 2: Architecture logicielle #3 : object oriented design

0. Object 101

Page 3: Architecture logicielle #3 : object oriented design

Object

In computer science, an object is a location in memory having a value and possibly referenced by an identifier. An object can be a variable, a data structure, or a function.Source : http://en.wikipedia.org

Page 4: Architecture logicielle #3 : object oriented design

Object-oriented programming

Object-Oriented programming is an approach to designing modular reusable software systems. The object-oriented approach is fundamentally a modelling approach.Source : http://en.wikipedia.org

Page 5: Architecture logicielle #3 : object oriented design

Class

In object-oriented programming, a class is an extensible program-code-template for creating objects, providing initial values for state and implementations of behavior.Source : http://en.wikipedia.org

Page 6: Architecture logicielle #3 : object oriented design

Class - PHP exemple

class Character {

private $firstName; private $lastName;

public function __construct($firstName, $lastName) { $this->firstName = $firstName; $this->lastName = $lastName; } }

Page 7: Architecture logicielle #3 : object oriented design

Instance

In object-oriented programming (OOP), an instance is a specific realization of any object. The creation of a realized instance is called instantiation.Source : http://en.wikipedia.org

Page 8: Architecture logicielle #3 : object oriented design

Instance - PHP exemple

$nedStark = new Character('Eddard', 'Stark');

$robertBaratheon = new Character('Robert', 'Baratheon');

Page 9: Architecture logicielle #3 : object oriented design

Attribute & method

A class contains data field descriptions (or properties, fields, data members, or attributes).Source : http://en.wikipedia.org

A method in object-oriented programming (OOP) is a procedure associated with an object class.Source : http://en.wikipedia.org

Page 10: Architecture logicielle #3 : object oriented design

Attribute & method - PHP exempleclass Character {

private $firstName; private $lastName; private $nickname;

public function __construct($firstName, $lastName, $nickname) { $this->firstName = $firstName; $this->lastName = $lastName; $this->nickname = $nickname; }

public function getFullName(){ return $this->firstName . ' ' . $this->lastName; }

public function getNickname(){ return $this->nickname; } }

$nedStark = new Character('Eddard', 'Stark', 'Ned'); echo $nedStark->getFullName(); // Eddard Stark echo $nedStark->getNickname(); // Ned

Page 11: Architecture logicielle #3 : object oriented design

Interface

In object-oriented languages, the term interface is often used to define an abstract type that contains no data or code, but defines behaviors as method signatures. A class having code and data for all the methods corresponding to that interface is said to implement that interface.Source : http://en.wikipedia.org

Page 12: Architecture logicielle #3 : object oriented design

Interface - PHP exempleinterface CharacterInterface { public function getFullName(); }

class Human implements CharacterInterface {

private $firstName; private $lastName;

public function __construct($firstName, $lastName) {…}

public function getFullName(){ return $this->firstName . ' ' . $this->lastName; } }

class Animal implements CharacterInterface {

private $name;

public function __construct($name) {…}

public function getFullName(){ return $this->name; } }

$nedStark = new Human('Eddard', 'Stark', 'Ned'); $nymeria = new Animal('Nymeria'); echo $nedStark->getFullName(); // Eddard Stark echo $nymeria->getFullName(); // Nymeria

Page 13: Architecture logicielle #3 : object oriented design

Inheritance

In object-oriented programming (OOP), inheritance is when an object or class is based on another object or class, using the same implementation (inheriting from a class) specifying implementation to maintain the same behavior.Source : http://en.wikipedia.org

Page 14: Architecture logicielle #3 : object oriented design

Inheritance - PHP exempleclass Human {

private $firstName; private $lastName;

public function __construct($firstName, $lastName) { $this->firstName = $firstName; $this->lastName = $lastName; }

public function getFullName(){ return $this->firstName . ' ' . $this->lastName; } }

class King extends Human {

private $reignStart; private $reignEnd;

public function setReign($reignStart, $reignEnd){ $this->reignStart = $reignStart; $this->reignEnd = $reignEnd; }

public function getReign(){ return $this->reignStart . " - " . $this->reignEnd; } } $robertBaratheon = new King('Robert', 'Baratheon'); $robertBaratheon->setReign(283, 298); echo $robertBaratheon->getFullName() . ' ( '.$robertBaratheon->getReign().' )'; // Robert Baratheon ( 283 - 298 )

Page 15: Architecture logicielle #3 : object oriented design

2. Are You Stupid?

Page 16: Architecture logicielle #3 : object oriented design

STUPID code, seriously?

Singleton

Tight Coupling

Untestability

Premature Optimization

Indescriptive Naming

Duplication

Page 17: Architecture logicielle #3 : object oriented design

2.1 Singleton

Page 18: Architecture logicielle #3 : object oriented design

Singleton syndrome

Page 19: Architecture logicielle #3 : object oriented design

class Database { const DB_DSN = 'mysql:host=localhost;port=3306;dbname=westeros'; const DB_USER = 'root'; const DB_PWD = 'root';

private $dbh; static private $instance;

private function connect() { if ($this->dbh instanceOf PDO) {return;}

$this->dbh = new PDO(self::DB_DSN, self::DB_USER, self::DB_PWD); }

public function query($sql) { $this->connect(); return $this->dbh->query($sql); }

public static function getInstance() { if (null !== self::$instance) { return self::$instance; }

self::$instance = new self(); return self::$instance; } }

Configuration difficile

singletons ~ variables globales

Couplages forts

Difficile à tester

Page 20: Architecture logicielle #3 : object oriented design

2.2 Tight Coupling

Page 21: Architecture logicielle #3 : object oriented design

Coupling ?

In software engineering, coupling is the manner and degree of interdependence between software modules; a measure of how closely connected two routines or modules are; the strength of the relationships between modules.Source : http://en.wikipedia.org

Page 22: Architecture logicielle #3 : object oriented design

Et en claire ?

If making a change in one module in your application requires you to change another

module, then coupling exists.

Page 23: Architecture logicielle #3 : object oriented design

Exemple de couplage fortclass Location { private $name; private $type; }

class Character {

private $firstName; private $lastName; private $location;

public function __construct($firstName, $lastName, $locationName, $locationType) { $this->firstName = $firstName; $this->lastName = $lastName; $this->location = new Location($locationName, $locationType); }

public function getFullName(){ return $this->firstName . ' ' . $this->lastName; } }

$nedStark = new Character('Eddard', 'Stark', 'Winterfell', 'Castle');

Page 24: Architecture logicielle #3 : object oriented design

Exemple de couplage faibleclass Location { private $name; private $type; }

class Character {

private $firstName; private $lastName; private $location;

public function __construct($firstName, $lastName, $location) { $this->firstName = $firstName; $this->lastName = $lastName; $this->location = $location; }

public function getFullName(){ return $this->firstName . ' ' . $this->lastName; } }

$winterfell = new Location($locationName, $locationType); $nedStark = new Character('Eddard', 'Stark', $winterfell);

Page 25: Architecture logicielle #3 : object oriented design

2.3 Untestability

Page 26: Architecture logicielle #3 : object oriented design

Testing ?

Page 27: Architecture logicielle #3 : object oriented design

In my opinion, testing should not be hard! No, really. Whenever you don't write unit tests because you don't have time, the real issue is that your code is bad, but that is another story.

Source : http://williamdurand.fr

Untested and Untestable

Page 28: Architecture logicielle #3 : object oriented design

2.4 Premature Optimization

Page 29: Architecture logicielle #3 : object oriented design

« Premature optimization is the root of all evil. »

Donald Knuth

Page 30: Architecture logicielle #3 : object oriented design

« If it doesn't work, it doesn't matter how fast it

doesn't work. »Mich Ravera

Page 31: Architecture logicielle #3 : object oriented design

2.5 Indescriptive Naming

Page 32: Architecture logicielle #3 : object oriented design

Give all entities mentioned in the code (DB tables, DB tables’ fields, variables, classes, functions, etc.) meaningful, descriptive names that make the code easily understood. The names should be so self-explanatory that it eliminates the need for comments in most cases.Source : Michael Zuskin

Self-explanatory

Page 33: Architecture logicielle #3 : object oriented design

Exemple : bad names

Page 34: Architecture logicielle #3 : object oriented design

« If you can't find a decent name for a class or a method, something is

probably wrong »William Durand

Page 35: Architecture logicielle #3 : object oriented design

class Char {

private $fn; private $ln;

public function __construct($fn, $ln) { $this->fn = $fn; $this->ln = $ln; }

public function getFnLn(){ return $this->fn . ' ' . $this->ln; } }

Exemple : abbreviations

Page 36: Architecture logicielle #3 : object oriented design

2.6 Duplication

Page 37: Architecture logicielle #3 : object oriented design

« Write Everything Twice »

WET ?

« We Enjoy Typing »

Page 38: Architecture logicielle #3 : object oriented design

Copy-and-paste programming is the production of highly repetitive computer programming code, as by copy and paste operations. It is primarily a pejorative term; those who use the term are often implying a lack of programming competence.Source : http://en.wikipedia.org

Copy And Paste Programming

Page 39: Architecture logicielle #3 : object oriented design

« Every piece of knowledge must have a single, unambiguous, authoritative representation within a system. »

Don’t Repeat Yourself

Andy Hunt & Dave Thomas

Page 40: Architecture logicielle #3 : object oriented design

The KISS principle states that most systems work best if they are kept simple rather than made complicated; therefore simplicity should be a key goal in design and unnecessary complexity should be avoided.

Keep it simple, stupid

Source : http://en.wikipedia.org

Page 41: Architecture logicielle #3 : object oriented design

3. Nope, Im solid !

Page 42: Architecture logicielle #3 : object oriented design

SOLID code ?

Single Responsibility Principle

Open/Closed Principle

Liskov Substitution Principle

Interface Segregation Principle

Dependency Inversion Principle

Page 43: Architecture logicielle #3 : object oriented design

3.1 Single Responsibility Principle

Page 44: Architecture logicielle #3 : object oriented design

Single Responsibility

A class should have one, and only one, reason to change.

Robert C. Martin

Page 45: Architecture logicielle #3 : object oriented design

The problemclass DataImporter { public function import($file) { $records = $this->loadFile($file); $this->importData($records); }

private function loadFile($file) { $records = array(); // transform CSV in $records return $records; }

private function importData(array $records) { // insert records in DB } }

Page 46: Architecture logicielle #3 : object oriented design

The solutionclass DataImporter {

private $loader; private $importer;

public function __construct($loader, $gateway) { $this->loader = $loader; $this->gateway = $gateway; }

public function import($file) { $records = $this->loader->load($file);

foreach ($records as $record) { $this->gateway->insert($record); } } }

Page 47: Architecture logicielle #3 : object oriented design

Kill the god class !

A "God Class" is an object that controls way too many other objects in the system and has grown beyond all logic to become The Class That

Does Everything.

Page 48: Architecture logicielle #3 : object oriented design

3.2 Open/Closed Principle

Page 49: Architecture logicielle #3 : object oriented design

Open/Closed

Objects or entities should be open for extension, but closed

for modification.Robert C. Martin

Page 50: Architecture logicielle #3 : object oriented design

The problem

class Circle { public $radius;

// Constructor function }

class Square { public $length;

// Constructor function }

class AreaCalculator {

protected $shapes;

// Constructor function

public function sum() { foreach($this->shapes as $shape) { if(is_a($shape, 'Square')) { $area[] = pow($shape->length, 2); } else if(is_a($shape, 'Circle')) { $area[] = pi() * pow($shape->radius, 2); } }

return array_sum($area); } }

$shapes = array( new Circle(2), new Square(5), new Square(6) );

$areas = new AreaCalculator($shapes); echo $areas->sum();

Source : https://scotch.io

Page 51: Architecture logicielle #3 : object oriented design

The solution (1)class Circle { public $radius;

// Constructor function

public function area() { return pi() * pow($this->radius, 2); } }

class Square { public $length;

// Constructor function

public function area() { return pow($this->length, 2); } }

class AreaCalculator {

protected $shapes;

// Constructor function

public function sum() { foreach($this->shapes as $shape) { $area[] = $shape->area(); } return array_sum($area); } }

$shapes = array( new Circle(2), new Square(5), new Square(6) );

$areas = new AreaCalculator($shapes); echo $areas->sum();

Source : https://scotch.io

Page 52: Architecture logicielle #3 : object oriented design

The solution (2)class AreaCalculator {

protected $shapes;

// Constructor function

public function sum() { foreach($this->shapes as $shape) { $area[] = $shape->area(); } return array_sum($area); } }

$shapes = array( new Circle(2), new Square(5), new Square(6) );

$areas = new AreaCalculator($shapes); echo $areas->sum();

interface ShapeInterface { public function area(); }

class Circle implements ShapeInterface { public $radius;

// Constructor function

public function area() { return pi() * pow($this->radius, 2); } }

class Square implements ShapeInterface { public $length;

// Constructor function

public function area() { return pow($this->length, 2); } }

Source : https://scotch.io

Page 53: Architecture logicielle #3 : object oriented design

3.3 Liskov Substitution Principle

Page 54: Architecture logicielle #3 : object oriented design

Liskov Substitution

Derived classes must be substitutable for their

base classes.Robert C. Martin

Page 55: Architecture logicielle #3 : object oriented design

Exemple

abstract class AbstractLoader implements FileLoader { public function load($file) { if (!file_exists($file)) { throw new \InvalidArgumentException(sprintf('%s does not exist.', $file)); } return []; } }

class CsvFileLoader extends AbstractLoader { public function load($file) { $records = parent::load($file); // Get records from file return $records; } }

Source : http://afsy.fr

Page 56: Architecture logicielle #3 : object oriented design

3.4 Interface Segregation Principle

Page 57: Architecture logicielle #3 : object oriented design

Interface Segregation

A client should never be forced to implement an interface that it doesn’t use or clients shouldn’t be forced to depend on methods they do not use.

Robert C. Martin

Page 58: Architecture logicielle #3 : object oriented design

Exemple

interface UrlGeneratorInterface { public function generate($name, $parameters = array()); }

interface UrlMatcherInterface { public function match($pathinfo); }

interface RouterInterface extends UrlMatcherInterface, UrlGeneratorInterface { public function getRouteCollection(); }

Source : http://afsy.fr

Page 59: Architecture logicielle #3 : object oriented design

3.5 Dependency Inversion Principle

Page 60: Architecture logicielle #3 : object oriented design

Dependency Inversion

Entities must depend on abstractions not on concretions. It states that the high level module must not depend on the

low level module, but they should depend on abstractions.

Robert C. Martin

Page 61: Architecture logicielle #3 : object oriented design

The problem

class DataImporter { private $loader; private $gateway;

public function __construct(CsvFileLoader $loader, DataGateway $gateway) { $this->loader = $loader; $this->gateway = $gateway; } }

Source : http://afsy.fr

Classes

Page 62: Architecture logicielle #3 : object oriented design

The solution

Source : http://afsy.fr

class DataImporter { private $loader; private $gateway;

public function __construct(FileLoader $loader, Gateway $gateway) { $this->loader = $loader; $this->gateway = $gateway; } }

Interfaces

Page 63: Architecture logicielle #3 : object oriented design

To be continued …