Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Manage your objects

Thomas Gasc
September 09, 2014

Manage your objects

Après une discution animée autour de concepts objets lors du dernier Apéro PHP de Montpellier, je me suis aperçu qu'un petit rappel des bases de la POO était nécessaire.

En 10 minutes, retour sur des concepts comme l'Injection de dépendances et sur certains design patterns (factory, singleton).

Le tout illustré avec des exemples en PHP.

Thomas Gasc

September 09, 2014
Tweet

More Decks by Thomas Gasc

Other Decks in Programming

Transcript

  1. Case study /* ask name */ fwrite(STDOUT, "enter your name

    :"); $name = trim(fgets(STDIN, 255)); /* ask birthday */ fwrite(STDOUT, "enter your birthday (yyyy/mm/dd) :"); $birthday = new DateTime(trim(fgets(STDIN, 255))); /* calculate the age */ $age = $birthday->diff(new DateTime()); /* display the result */ fwrite( STDOUT, sprintf(PHP_EOL."hello %s you've got %s years old.", $name, $age->y) );
  2. Application Class Diagram Reader + handle + length + read(msg)

    Writer + handle + write(msg) AgeCalculator + execute()
  3. // src/Reader.php class Reader { private $handle = STDIN; private

    $length = 255; private $writer; public function __construct() { $this->writer = new Writer(); } public function read($msg) { $this->writer->write($msg); return trim(fgets($this->handle, $this->length)); } }
  4. // src/AgeCalculator.php class AgeCalculator { private $reader, $writer; public function

    __construct() { $this->reader = new Reader(); $this->writer = new Writer(); } public function execute() { $name = $this->reader->read('your name:'); $birthday = new DateTime( $this->reader->read('your birthday (yyyy/mm/dd):') ); $age = $birthday->diff(new DateTime('now')); $this->writer->write( sprintf("hello %s you've got %s years old.", $name, $age->y) ); } }
  5. Running the application // age-calculator.php $ageCalculator = new AgeCalculator(); $ageCalculator->execute();

    $ php age-calculator.php your name: thomas your birthday (yyyy/mm/dd): 1994/01/01 hello thomas you've got 20 years old.
  6. // src/Reader.php class Reader { private $handle, $length, $writer; public

    function __construct(Writer $writer = null, $handle = STDIN, $length = 255) { $this->handle = $handle; $this->length = $length; $this->writer = $writer; } public function read($msg) { if ($this->writer) { $this->writer->write($msg); } return trim(fgets($this->handle, $this->length)); } }
  7. // age-calculator.php $writer = new Writer(); $reader = new Reader($writer);

    $ageCalculator = new AgeCalculator($writer, $reader); $ageCalculator->execute();
  8. // age-calculator.php $writer = new Writer(fopen('result', 'w+')); $reader = new

    Reader(null, fopen('data', 'r')); $ageCalculator = new AgeCalculator($writer, $reader); $ageCalculator->execute();
  9. // config/cli.php return [ 'Writer' => DI\object()->constructor(), 'Reader' => DI\object()

    ->constructor(DI\link('Writer')), 'AgeCalculator' => DI\object() ->constructor(DI\link('Writer'), DI\link('Reader')), ];
  10. // age-calculator.php require 'vendor/autoload.php'; $builder = new \DI\ContainerBuilder(); $builder->addDefinitions('config/cli.php'); $container

    = $builder->build(); $ageCalculator = $container->get('AgeCalculator'); $ageCalculator->execute();
  11. // config/file.php return [ 'handle.result' => fopen('result', 'w+'), 'handle.data' =>

    fopen('data', 'r'), 'Writer' => DI\object() ->constructor(DI\link('handle.result')), 'Reader' => DI\object() ->constructor(null, DI\link('handle.data')), 'AgeCalculator' => DI\object() ->constructor(DI\link('Writer'), DI\link('Reader')), ];
  12. Factory Design Pattern Deals with the problem of creating objects

    without specifying the exact class of object that will be created
  13. << abstract >> Factory + create() WriterFactory ReaderFactory FileWriter Writer

    Reader FileReader << interface >> ReaderInterface << interface >> WriterInterface creates creates extends extends extends extends uses extends extends + setWriter(writer) + read(msg) + write(msg)
  14. // src/FileWriter.php class FileWriter extends Writer { public function __construct($filename,

    $length = 255) { $this->handle = fopen($filename, 'w+'); $this->length = $length; } } // src/Filereader.php class FileReader extends Reader { public function __construct($filename, $length = 255) { $this->handle = fopen($filename, 'r'); $this->length = $length; } }
  15. // src/Factory.php abstract class Factory { private $class; public function

    __construct($class) { $this->class = new ReflectionClass($class); } protected abstract function configure(ReflectionClass $class); public function create($args = array()) { return $this->class->newInstanceArgs($args); } }
  16. // config/file.php return [ 'writer.class' => 'FileWriter', 'reader.class' => 'FileReader',

    'data.file' => 'data', 'result.file' => 'result', 'WriterFactory' => DI\object()->constructor(DI\link('writer.class')), 'ReaderFactory' => DI\object() ->constructor( DI\link('reader.class')), DI\factory(function ($container) { return $container ->get('WriterFactory') ->create(array($container->get('result.file'))) ; }), DI\factory(function ($container) { return $container ->get('ReaderFactory') ->create(array($container->get('data.file'))) ; } ), 'AgeCalculator' => DI\object()->constructor(DI\link('writer'), DI\link('reader')), ];