Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Architecture logicielle #3 : object oriented design

969 views

Published on

Published in: Software
  • Be the first to comment

  • Be the first to like this

Architecture logicielle #3 : object oriented design

  1. 1. Architecture logicielle : Object-oriented design
  2. 2. 0. Object 101
  3. 3. 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
  4. 4. 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
  5. 5. 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
  6. 6. Class - PHP exemple class Character { private $firstName; private $lastName; public function __construct($firstName, $lastName) { $this->firstName = $firstName; $this->lastName = $lastName; } }
  7. 7. 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
  8. 8. Instance - PHP exemple $nedStark = new Character('Eddard', 'Stark'); $robertBaratheon = new Character('Robert', 'Baratheon');
  9. 9. 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
  10. 10. Attribute & method - PHP exemple class 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
  11. 11. 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
  12. 12. Interface - PHP exemple interface 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
  13. 13. 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
  14. 14. Inheritance - PHP exemple class 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 )
  15. 15. 2. Are You Stupid?
  16. 16. STUPID code, seriously? Singleton Tight Coupling Untestability Premature Optimization Indescriptive Naming Duplication
  17. 17. 2.1 Singleton
  18. 18. Singleton syndrome
  19. 19. 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
  20. 20. 2.2 Tight Coupling
  21. 21. 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
  22. 22. Et en claire ? If making a change in one module in your application requires you to change another module, then coupling exists.
  23. 23. Exemple de couplage fort class 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');
  24. 24. Exemple de couplage faible class 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);
  25. 25. 2.3 Untestability
  26. 26. Testing ?
  27. 27. 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
  28. 28. 2.4 Premature Optimization
  29. 29. « Premature optimization is the root of all evil. » Donald Knuth
  30. 30. « If it doesn't work, it doesn't matter how fast it doesn't work. » Mich Ravera
  31. 31. 2.5 Indescriptive Naming
  32. 32. 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
  33. 33. Exemple : bad names
  34. 34. « If you can't find a decent name for a class or a method, something is probably wrong » William Durand
  35. 35. 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
  36. 36. 2.6 Duplication
  37. 37. « Write Everything Twice » WET ? « We Enjoy Typing »
  38. 38. 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
  39. 39. « Every piece of knowledge must have a single, unambiguous, authoritative representation within a system. » Don’t Repeat Yourself Andy Hunt & Dave Thomas
  40. 40. 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
  41. 41. 3. Nope, Im solid !
  42. 42. SOLID code ? Single Responsibility Principle Open/Closed Principle Liskov Substitution Principle Interface Segregation Principle Dependency Inversion Principle
  43. 43. 3.1 Single Responsibility Principle
  44. 44. Single Responsibility A class should have one, and only one, reason to change. Robert C. Martin
  45. 45. The problem class 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 } }
  46. 46. The solution class 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); } } }
  47. 47. 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.
  48. 48. 3.2 Open/Closed Principle
  49. 49. Open/Closed Objects or entities should be open for extension, but closed for modification. Robert C. Martin
  50. 50. 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
  51. 51. 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
  52. 52. 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
  53. 53. 3.3 Liskov Substitution Principle
  54. 54. Liskov Substitution Derived classes must be substitutable for their base classes.Robert C. Martin
  55. 55. 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
  56. 56. 3.4 Interface Segregation Principle
  57. 57. 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
  58. 58. 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
  59. 59. 3.5 Dependency Inversion Principle
  60. 60. 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
  61. 61. 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
  62. 62. 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
  63. 63. To be continued …

×