Publicité

Design Patterns

PHP Developer à self-employed
3 Mar 2011
Publicité

Contenu connexe

Publicité
Publicité

Design Patterns

  1. Design Patterns Lorna Mitchell PHP East Midlands 3 March 2011 rd
  2. Design Patterns ● Common language ● Familiar problems ● NOT rocket science or the holy grail
  3. Some Common Patterns ● Singleton ● Registry ● Factory ● Adapter ● Decorator ● Observer
  4. Singleton ● Only one object of this type can exist ● Private constructor ● Method to return the object ● Class manages instantiation
  5. Singleton Example 1 <?php 2 3 class Singleton 4 { 5 private static $classInstance; 6 7 private function __construct () {} 8 9 static function getInstance () { 10 if (! isset(self::$classInstance)) { 11 self::$classInstance = new Singleton(); 12 } 13 return (self::$ classInstance); 14 } 15 }
  6. Singleton Is Uncool ● Hard to test ● Dependency injection is better ● Terribly unfashionable ● Better than a global variable
  7. Registry ● A singleton of singletons ● Zend_Registry is an example ● Can instantiate, or just store
  8. Registry Example 1 class Registry 2 { 3 private static $storage; 4 5 private function __construct () {} 6 7 public function set($key, $value) { 8 self::$storage[$key] = $value; 9 } 10 11 public function get($key) { 12 if(array_key_exists($key, self::$storage)) { 13 return self::$storage[$key]; 14 } else { 15 return false; 16 } 17 } 19 18 } 20 Registry::set('shinyThing', new StdClass()); 21 // later ... 22 $shiny = Registry::get('shinyThing');
  9. Factory ● Logic involved in creating an object ● Objects usually related ● Helpful for testing
  10. Factory Example 1 class WidgetFactory 2 { 3 public function getWiget($type) { 4 switch($type) { 5 case 'DatePicker': 6 // assume simple look/feel, use $options 7 return new SimpleDatePicker($options); 8 break; 9 default: 10 // do nothing, invalid widget type 11 break; 12 } 13 } 14 } 15 16 $widget_factory = new WidgetFactory(); 17 $picker = $widget_factory->getWidget('DatePicker'); 18 $picker->render();
  11. Combining Patterns ● A singleton is also a factory ● Can combine factory and registry
  12. Adapter ● Making one object look like another ● Adapter class presents one interface, and may map to another ● Target class left unchanged ● PDO is a great example
  13. Adapter Example 1 <?php 2 3 class User { 4 function getUsername() { 5 return "joe"; 6 } 7 8 function getId() { 9 return 42; 10 } 11 12 function isValid($username, $password) { 13 return true; 14 } 15 } 16 17 $user = new User(); 18 if($user->isValid('joe','secret')) { 19 echo 'Hi ' . $user->getUsername(); 20 }
  14. Adapter Example 1 <?php 2 3 class SuperDuperUser { 4 function getUser() { 5 return array ("username" => "joe", "id" => 42); 6 } 7 8 function areCredentialsOK($usr, $pass) { 9 return true; 10 } 11 }
  15. Adapter Example 13 class UserAdapter { 14 function __construct() { 15 $this->_original = new SuperDuperUser(); 16 } 18 function getUsername() { 19 $user = $this->_original->getUser(); 20 return $user['username']; 21 } 22 function getId() { 23 $user = $this->_original->getUser(); 24 return $user['id']; 25 } 27 function isValid($username, $password) { 28 return $this->_original->areCredentialsOK($usr,$pass); 29 } 30 } 31 32 $user = new UserAdapter(); 33 if($user->isValid('joe','secret')) { 34 echo 'Hi ' . $user->getUsername(); 35 }
  16. Decorator ● Unintrusive ● Object encloses another object ● think of pass-the-parcel! ● Often literally for visual decoration
  17. Decorator Example 1 <?php 2 3 Interface WeatherInterface { 4 public function getWeather(); 5 } 6 7 class WeatherBot implements WeatherInterface { 8 public function getWeather() { 9 // imagine something more complicated 10 return 'Sunny'; 11 } 12 } 13
  18. Decorator Example 14 class WordyDecorator implements WeatherInterface 15 { 16 protected $weatherInterface; 18 public function __construct (WeatherInterface $weather) { 19 $this->weatherInterface = $weather; 20 } 22 public function getWeather () { 23 $string = 'Today: '.$this->weatherInterface->getWeather(); 24 return ($string); 25 } 26 } 27 28 class BorderDecorator implements WeatherInterface 29 { 30 protected $weatherInterface; 32 public function __construct (WeatherInterface $weather) { 33 $this->weatherInterface = $weather; 34 } 36 public function getWeather () { 37 $string = '~{'.$this->weatherInterface->getWeather().'}~'; 38 return ($string); 39 } 40 }
  19. Decorator Example 42 $weather = new WordyDecorator(new WeatherBot); 43 echo $weather->getWeather(); 44
  20. Observer ● Both subject and object know about the pattern ● Observer requests updates ● Observee notifies everyone on change ● Also called publish/subscribe
  21. Observer Example Target Notify Register Interest Observer
  22. Observer Example 1 class BankAccount 2 { 3 protected $amount; 4 protected $observer; 5 public function __construct ($amount) { 6 $this->observer = new MoneyObserver(); 7 $this->setAmount($amount); 8 } 9 protected function setAmount ($amount) { 10 $this->amount = $amount; 11 $this->notify(); 12 } 13 public function deposit ($money) { 14 $this->setAmount($this->amount + $money); 15 } 16 public function withdraw ($money) { 17 $this->setAmount($this->amount - $money); 18 } 19 public function notify () { 20 $this->observer->update($this); 21 } 22 }
  23. Observer Example 24 class MoneyObserver 25 { 26 public function update (BankAccount $act) { 27 echo date('H:i:s.u') . ': Balance change: &pound;' 28 . $act->balance() . '<br />'; 29 } 30 }
  24. Design Patterns ● Singleton ● Registry ● Factory ● Adapter ● Decorator ● Observer ● ... and many more!
  25. Design Patterns ● Common vocabulary ● NOT a silver bullet ● Another tool in the box ● Remember: All things in moderation!
  26. Resources ● “Gang Of Four” book: Design Patterns: Elements of Reusable Object-Oriented Software ● Gamma, Helm, Johnson, Vlissides ● Patterns of Enterprise Application Architecture ● Fowler ● http://www.fluffycat.com/PHP-Design-Patterns/
  27. Questions?
Publicité