Singleton
●
Only one object of this type can exist
●
Private constructor
●
Method to return the object
●
Class manages instantiation
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 }
Singleton Is Uncool
●
Hard to test
●
Dependency injection is better
●
Terribly unfashionable
●
Better than a global variable
Registry
●
A singleton of singletons
●
Zend_Registry is an example
●
Can instantiate, or just store
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');
Factory
●
Logic involved in creating an object
●
Objects usually related
●
Helpful for testing
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();
Combining Patterns
●
A singleton is also a factory
●
Can combine factory and registry
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
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 }
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 }
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 }
Decorator
●
Unintrusive
●
Object encloses another object
●
think of pass-the-parcel!
●
Often literally for visual decoration
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
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 }
Observer
●
Both subject and object know about the pattern
●
Observer requests updates
●
Observee notifies everyone on change
●
Also called publish/subscribe