Design Patterns

27
Design Patterns Lorna Mitchell PHP East Midlands 3 rd March 2011

description

The short design patterns talk I delivered at PHP East Midlands in March 2011

Transcript of Design Patterns

Page 1: Design Patterns

Design Patterns

Lorna MitchellPHP East Midlands

3rd March 2011

Page 2: Design Patterns

Design Patterns● Common language● Familiar problems● NOT rocket science or the holy grail

Page 3: Design Patterns

Some Common Patterns● Singleton● Registry● Factory● Adapter● Decorator● Observer

Page 4: Design Patterns

Singleton● Only one object of this type can exist● Private constructor● Method to return the object● Class manages instantiation

Page 5: Design Patterns

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 }

Page 6: Design Patterns

Singleton Is Uncool● Hard to test● Dependency injection is better● Terribly unfashionable● Better than a global variable

Page 7: Design Patterns

Registry● A singleton of singletons● Zend_Registry is an example● Can instantiate, or just store

Page 8: Design Patterns

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 } 18 } 19

20 Registry::set('shinyThing', new StdClass()); 21 // later ... 22 $shiny = Registry::get('shinyThing');

Page 9: Design Patterns

Factory● Logic involved in creating an object● Objects usually related● Helpful for testing

Page 10: Design Patterns

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();

Page 11: Design Patterns

Combining Patterns● A singleton is also a factory● Can combine factory and registry

Page 12: Design Patterns

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

Page 13: Design Patterns

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 }

Page 14: Design Patterns

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 }

Page 15: Design Patterns

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 } 36

Page 16: Design Patterns

Decorator● Unintrusive● Object encloses another object

● think of pass-the-parcel!● Often literally for visual decoration

Page 17: Design Patterns

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

Page 18: Design Patterns

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 }

Page 19: Design Patterns

Decorator Example

42 $weather = new WordyDecorator(new WeatherBot); 43 echo $weather->getWeather(); 44

Page 20: Design Patterns

Observer● Both subject and object know about the pattern● Observer requests updates● Observee notifies everyone on change● Also called publish/subscribe

Page 21: Design Patterns

Observer Example

Target

Observer

Register Interest

Notify

Page 22: Design Patterns

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 }

Page 23: Design Patterns

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 }

Page 24: Design Patterns

Design Patterns● Singleton● Registry● Factory● Adapter● Decorator● Observer● ... and many more!

Page 25: Design Patterns

Design Patterns● Common vocabulary● NOT a silver bullet● Another tool in the box● Remember: All things in moderation!

Page 26: Design Patterns

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/

Page 27: Design Patterns

Questions?