Sheraton Gateway Suite O'Hare May 20, 2008
Jun 06, 2015
Sheraton Gateway Suite O'HareMay 20, 2008
Sheraton Gateway Suite O'HareMay 20, 2008
Design Patterns in PHP
Sheraton Gateway Suite O'HareMay 20, 2008
Jason E. Sweathttp://[email protected]
Design Patterns in PHP
Sheraton Gateway Suite O'HareMay 20, 2008 2Sheraton Gateway Suite O'HareMay 20, 2008
Technical Conference Presentation Pattern
2
• Design Pattern–The Classic Tech Talk
• Implementation:–Tell ‘em what your are going to tell ‘em–Tell ‘em–Tell ‘em what you told ‘em
• Forces:–Communication information to an audience
Sheraton Gateway Suite O'HareMay 20, 2008 3
The “Pattern” of this presentation
• Definition of Design Patterns
• Catalog of Design Patterns–Name and define each pattern–Review example PHP code–Forces driving use
• Conclusion
Sheraton Gateway Suite O'HareMay 20, 2008 4
What is a Design Pattern?
• Commonly recognized, well developed and tested solution to a specific problem in a given context
• A specific way to organize a portion of your program—a code structure
• A name – a short hand way to communicate a design decision with other programmers familiar with patterns
• Obligatory reference: Christopher Alexander “A Pattern Language”
Sheraton Gateway Suite O'HareMay 20, 2008 5
What a Design Pattern Isn’t
• Library• Framework• Copy & Paste Example Code
Sheraton Gateway Suite O'HareMay 20, 2008 5
What a Design Pattern Isn’t
• Library• Framework• Copy & Paste Example Code
Your code and your problems are required to realize a design pattern.
Sheraton Gateway Suite O'HareMay 20, 2008 6
Reification
• Reify - To make real• Reification – The process of making real
–Definition from “Holub on Patterns”
Sheraton Gateway Suite O'HareMay 20, 2008 7
Pattern Usage
• Write code as usual• Feel a pain point (complex design issues,
bad code smells)• Be aware of Design Patterns, specifically
ones which solve the problem you are experiencing
• Refactor/write your code to apply the pattern to your problem
• Help apply DRY principal
Sheraton Gateway Suite O'HareMay 20, 2008 8
Pattern Anti-Usage
• Big up front design–Plan which patterns you will need ahead of time–Violation of YAGNI
• Apply patterns where the problem they solve does not exist–Create complexity where there is no need for it–This applies to nearly every isolated example!!
Sheraton Gateway Suite O'HareMay 20, 2008 8
Pattern Anti-Usage
• Big up front design–Plan which patterns you will need ahead of time–Violation of YAGNI
• Apply patterns where the problem they solve does not exist–Create complexity where there is no need for it–This applies to nearly every isolated example!!
Design Patterns can make coding complex problems easier.
Use them wisely and appropriately.
Sheraton Gateway Suite O'HareMay 20, 2008 9
Design Pattern Online Resources
• PHP Related• http://www.patternsforphp.com/• http://www.phppatterns.com/ • http://www.sitepoint.com/forums/forumdisplay.php?f=147
• Classic • http://www.vincehuston.org/dp/ • http://c2.com/cgi/wiki?DesignPatterns • http://www.martinfowler.com/eaaCatalog/index.html • http://en.wikipedia.org/wiki/Design_pattern_
%28computer_science%29
Sheraton Gateway Suite O'HareMay 20, 2008 10
Catalog Approach
• Name• Problem – what problem and context is the
pattern a solution to• Example – some concrete web application
related problems• Code – in PHP• Forces
–Why you would want to use this pattern–What would cause you to avoid it
Many pattern catalogs are much more detailed. We are going to limit the scope of the catalog to these essential elements.
Sheraton Gateway Suite O'HareMay 20, 2008 11
Singleton
• Problem: How can you make sure you are using a single instance of a class, and provide easy access to this instance?
• Example: database connections, factories, registries
Sheraton Gateway Suite O'HareMay 20, 2008 12
Singleton
• Code
• Tests
Sheraton Gateway Suite O'HareMay 20, 2008 13
Singleton - Forces
• For–Ensure object is configured correctly before
access–Ensure there is only one instance of the object
possible
• Against–Global access–Hard coding dependencies
Sheraton Gateway Suite O'HareMay 20, 2008 14
Factory
• Problem: How can you centralize logic related to creation of objects?
• Example: Create instances of a CatalogItems
Sheraton Gateway Suite O'HareMay 20, 2008 14
Factory
• Problem: How can you centralize logic related to creation of objects?
• Example: Create instances of a CatalogItems
There are several related creational patterns: FactoryMethod, AbstractFactory, Builder. In PHP, any method which returns an object is often referred to as a Factory. The dynamic typing of PHP may make implementing these in strict accordance with the patterns excessive for most projects needs.
Sheraton Gateway Suite O'HareMay 20, 2008 15
FactoryMethod
• Class Diagram
Sheraton Gateway Suite O'HareMay 20, 2008 16
FactoryMethod
• code
Sheraton Gateway Suite O'HareMay 20, 2008 17
FactoryMethod
• More “PHPish” code
Sheraton Gateway Suite O'HareMay 20, 2008 18
FactoryMethod - Code in action
Sheraton Gateway Suite O'HareMay 20, 2008 19
FactoryMethod - Forces
• For–Isolate construction complexity–Promote decoupling code
• Against–One additional layer of indirection between the
construction of an object and it’s use
Sheraton Gateway Suite O'HareMay 20, 2008 20
TemplateMethod
• Problem: How can you structure a class hierarchy to allow new implementations via subclassing?
• Example: different shipping calculation models in a shopping cart
Sheraton Gateway Suite O'HareMay 20, 2008 21
TemplateMethod
• code
Sheraton Gateway Suite O'HareMay 20, 2008 22
TemplateMethod
• Code continued
Sheraton Gateway Suite O'HareMay 20, 2008 23
TemplateMethod
• Tests
Sheraton Gateway Suite O'HareMay 20, 2008 24
TemplateMethod - Forces
• For–Lets subclasses vary algorithm behavior–Reduces code duplication
• Against–Forces inheritance
Sheraton Gateway Suite O'HareMay 20, 2008 25
Strategy
• Problem: How can you encapsulate an algorithm in an object, so that it can be selected at run-time?
• Example: different shipping calculation models in a shopping cart
Sheraton Gateway Suite O'HareMay 20, 2008 25
Strategy
• Problem: How can you encapsulate an algorithm in an object, so that it can be selected at run-time?
• Example: different shipping calculation models in a shopping cart
Quote seen on the internet: “Eventually, everything starts to look like a Strategy.” This is because the Strategy pattern implementation emphasizes the OO principal of polymorphism, making it very powerful in practice.
Sheraton Gateway Suite O'HareMay 20, 2008 26
Strategy
• code
Sheraton Gateway Suite O'HareMay 20, 2008 27
Strategy
• More code
Sheraton Gateway Suite O'HareMay 20, 2008 28
Strategy
• Tests
Sheraton Gateway Suite O'HareMay 20, 2008 29
Strategy - Forces
• For–Heart of favor composition over inheritance–Elimination of replicated control logic–Select “guts” of an object at run-time
• Against–Code complexity
Sheraton Gateway Suite O'HareMay 20, 2008 30
State
• Problem: How can you allow an object to alter its behavior when its internal state changes, such that the object will appear to change its class?–Put another way: How can I implement an object
which behaves like the Strategy pattern, but can change Strategies over the lifetime of the object
• Example: same shopping cart checkout–Perhaps you want to list the shipping rates for all
available options reusing the strategy code already implemented in the prior example
Sheraton Gateway Suite O'HareMay 20, 2008 31
State - Code
Sheraton Gateway Suite O'HareMay 20, 2008 32
State
• Tests
Sheraton Gateway Suite O'HareMay 20, 2008 33
State – Forces
• For–Power of Strategy with more flexibility
• Against–Similar code complexity as Strategy
Sheraton Gateway Suite O'HareMay 20, 2008 34
Proxy
• Problem: How can you provide surrogate control to an object?
• Example: remote resources, lazy instantiation, access control
Sheraton Gateway Suite O'HareMay 20, 2008 35
Proxy (Access)
• Code
Sheraton Gateway Suite O'HareMay 20, 2008 36
Proxy (Access)
• Tests
Sheraton Gateway Suite O'HareMay 20, 2008 37
Proxy (Lazy)
• Code
Sheraton Gateway Suite O'HareMay 20, 2008 38
Proxy – Forces
• For–Need to add additional functionality without
changing the original classes responsibilities–Need flexibility to change functionality after the
object is already instantiated
• Against–Is the flexibility required?
Sheraton Gateway Suite O'HareMay 20, 2008 39
Decorator
• Problem: How can you add capabilities to an object dynamically?
• Example: caching, error/warning indication
The Decorator pattern can allow you to “trump” inheritance, allowing you to deploy a very flexible solution without repeating code in many locations inside of a class hierarchy.
Sheraton Gateway Suite O'HareMay 20, 2008 40
Decorator
• Illustrating the problem in UML– A hypothetical widget library to generate forms
– But we might want to have some widgets labeled…
Sheraton Gateway Suite O'HareMay 20, 2008 41
Decorator
But sometimes you want to flag the control as in error after form validation, and this might apply to either the normal or a labeled widget…
Sheraton Gateway Suite O'HareMay 20, 2008 42
Decorator
Yuck… and we only showed two kinds of “Widget”
Sheraton Gateway Suite O'HareMay 20, 2008 43
Decorator
Sheraton Gateway Suite O'HareMay 20, 2008 44
Decorator
• Code
Sheraton Gateway Suite O'HareMay 20, 2008 45
Decorator
Sheraton Gateway Suite O'HareMay 20, 2008 46
Decorator - Forces
• For–Eliminate code replication in class hierarchy–Flexibility–Powerful use of Polymorphism
• Against–Additional code to create the object–May be hard to understand the effects of objects
decorated multiple times
Sheraton Gateway Suite O'HareMay 20, 2008 47
SPL
• Standard PHP Library• Documentation
–Official - http://www.php.net/manual/en/ref.spl.php–Real - http://www.php.net/~helly/php/ext/spl/
• SPL is a collection of interfaces and classes that are meant to solve standard problems.–Many SPL classes implement design patterns
Sheraton Gateway Suite O'HareMay 20, 2008 48
Iterator
• Problem: How can you process a collection of objects in a uniform manner?
• Examples: arrays, directories/files, db record sets, XML elements
Sheraton Gateway Suite O'HareMay 20, 2008 49
Iterator
• foreach is your friend• Hooray for object handles!
Sheraton Gateway Suite O'HareMay 20, 2008 50
Iterator
• If you are too lazy to look up the methods in the Iterator interface, PHP will let you know:
Sheraton Gateway Suite O'HareMay 20, 2008 51
Iterator - Code
Sheraton Gateway Suite O'HareMay 20, 2008 52
Iterator
• Tests
Sheraton Gateway Suite O'HareMay 20, 2008 53
Iterator - Forces
• For–Uniform handling of different data sources
• Against–Can your code compete with an array?
Sheraton Gateway Suite O'HareMay 20, 2008 54
Observer
• Problem: How can you effectively separate objects which produce data from objects which need to consume this data?
• Example: logging to one or more styles of output (text file, syslog, email, HTML output, etc.)
Sheraton Gateway Suite O'HareMay 20, 2008 55
Observer
Sheraton Gateway Suite O'HareMay 20, 2008 56
Observer
• In SPL – interfaces
Sheraton Gateway Suite O'HareMay 20, 2008 57
Observer
• Code – • A Subject
Sheraton Gateway Suite O'HareMay 20, 2008 58
Observer
• Code – putting it to use:
Sheraton Gateway Suite O'HareMay 20, 2008 59
Observer
• Tests
Sheraton Gateway Suite O'HareMay 20, 2008 60
Observer - Forces
• For–Effective separation of the producer of data from
the consumers
• Against–The common theme – code complexity, did you
really need the flexibility Observer provides?
Sheraton Gateway Suite O'HareMay 20, 2008 61
A pair of Data Access Patterns
• In PHP, nearly every application accesses data in a database – what patterns have evolved in this area?–ActiveRecord–TableDataGateway
CREATE TABLE `bookmark` ( `id` INT NOT NULL AUTO_INCREMENT , `url` VARCHAR( 255 ) NOT NULL , `name` VARCHAR( 255 ) NOT NULL , `description` MEDIUMTEXT, `tag` VARCHAR( 50 ) , `created` DATETIME NOT NULL , `updated` DATETIME NOT NULL ,PRIMARY KEY ( `id` ))
Sheraton Gateway Suite O'HareMay 20, 2008 62
A database access library
• http://adodb.sf.net/ require_once 'adodb/adodb.inc.php';
class DB { //static class, we do not need a constructor private function __construct() {} public static function conn() { static $conn; if (!$conn) { $conn = adoNewConnection('mysql'); $conn->connect('localhost', 'phpauser‘ , 'phpapass', 'phpa'); $conn->setFetchMode(ADODB_FETCH_ASSOC); } return $conn; }}
Sheraton Gateway Suite O'HareMay 20, 2008 63
ActiveRecord
• How can we have and object which both knows business logic and how to persist itself in a database?
Sheraton Gateway Suite O'HareMay 20, 2008 64
ActiveRecord - Code
• Some properties
• And a little business logic – id is read only
class Bookmark { const NEW_BOOKMARK = -1; protected $id = -1; protected $conn; public $url; public $name; public $description; public $tag; public $created; public $updated; public function getId() { return $this->id; }}
Sheraton Gateway Suite O'HareMay 20, 2008 65
ActiveRecord – Code – constructor, find self?
class Bookmark { const SELECT_BY_ID = 'select * from bookmark where id = ?'; public function __construct($id=false, $conn=false) { $this->conn = ($conn) ? $conn : DB::conn(); if ($id) { $rs = $this->conn->execute( self::SELECT_BY_ID ,array((int)$id));
if ($rs) { $row = $rs->fetchRow(); foreach($row as $field => $value) { $this->$field = $value; } } else { throw new Exception('DB Error: '.$this->conn->errorMsg()); } } }}
Sheraton Gateway Suite O'HareMay 20, 2008 66
ActiveRecord – code
• Great, now we can find ourself, how can we make changes?
public function save() { if ($this->id == self::NEW_BOOKMARK) { $this->insert(); } else { $this->update(); } $this->setTimeStamps(); }
Sheraton Gateway Suite O'HareMay 20, 2008 67
ActiveRecord – update()
const UPDATE_SQL = " update bookmark set url = ?, name = ?, description = ?, tag = ?, updated = now() where id = ? "; protected function update() { $this->conn->execute( self::UPDATE_SQL ,array( $this->url, $this->name, $this->description, $this->tag, $this->id)); }
Sheraton Gateway Suite O'HareMay 20, 2008 68
ActiveRecord - Forces
• For–Simplest data pattern for “row at a time” handling
of data
• Against–Mixing data access and business logic in a single
class – low cohesion
Sheraton Gateway Suite O'HareMay 20, 2008 69
TableDataGateway
• How can we give ourselves access to many rows of data from a table easily?
Sheraton Gateway Suite O'HareMay 20, 2008 70
TableDataGateway - code
class BookmarkGateway { protected $conn; public function __construct($conn) { $this->conn = $conn; }
public function findAll() { $rs = $this->conn->execute('select * from bookmark'); if ($rs) { return $rs->getArray(); } else { throw new Exception('DB Error: ' .$this->conn->errorMsg()); } }}
Sheraton Gateway Suite O'HareMay 20, 2008 71
TableDataGateway – add()
const INSERT_SQL = " insert into bookmark (url, name, description, tag , created, updated) values (?, ?, ?, ?, now(), now()) "; public function add($url, $name, $description, $group) { $rs = $this->conn->execute( self::INSERT_SQL ,array($url, $name, $description, $group)); if (!$rs) { throw new Exception('DB Error: '.$this->conn->errorMsg()); } }
Sheraton Gateway Suite O'HareMay 20, 2008 72
TableDataGateway – Forces
• For–Simplest data pattern for multiple row access of
data from a table–Centralize database access for table in a single
location in your code
• Against–Managing code in separate locations – sql
statement is now located in a find method instead of embedded in code
Sheraton Gateway Suite O'HareMay 20, 2008 73
Reading Resources
Sheraton Gateway Suite O'HareMay 20, 2008 73
Reading Resources
• GoF - Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides Design Patterns: Elements of reusable object-oriented software. Addison-Wesley, 1995
Sheraton Gateway Suite O'HareMay 20, 2008 73
Reading Resources
• GoF - Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides Design Patterns: Elements of reusable object-oriented software. Addison-Wesley, 1995
• PoEAA - Martin Fowler Patterns of Enterprise Application Architecture Addison-Wesley, 2003
Sheraton Gateway Suite O'HareMay 20, 2008 73
Reading Resources
• GoF - Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides Design Patterns: Elements of reusable object-oriented software. Addison-Wesley, 1995
• PoEAA - Martin Fowler Patterns of Enterprise Application Architecture Addison-Wesley, 2003
• Allen Holub Holub on Patterns: Learning design patterns by looking at code Apress, 2004
• Robert Martin Agile Software Development Prentice Hall, 2003• Clifton Nock Data Access Patterns Addison-Wesley, 2004• George Schlossnagle Advanced PHP Programming Sams Pub., 2004• Alan Shalloway and James R. Trott Design Patterns Explained, Addison-
Wesley, 2005• Rebecca Wirfs-Brock and Alan McKean Roles, Responsibilities and
Collaborations Addison-Wesley, 2003• Matt Zandstra Php 5 Objects, Patterns, Practice Apress, 2004
Sheraton Gateway Suite O'HareMay 20, 2008 73
Reading Resources
• GoF - Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides Design Patterns: Elements of reusable object-oriented software. Addison-Wesley, 1995
• PoEAA - Martin Fowler Patterns of Enterprise Application Architecture Addison-Wesley, 2003
• Allen Holub Holub on Patterns: Learning design patterns by looking at code Apress, 2004
• Robert Martin Agile Software Development Prentice Hall, 2003• Clifton Nock Data Access Patterns Addison-Wesley, 2004• George Schlossnagle Advanced PHP Programming Sams Pub., 2004• Alan Shalloway and James R. Trott Design Patterns Explained, Addison-
Wesley, 2005• Rebecca Wirfs-Brock and Alan McKean Roles, Responsibilities and
Collaborations Addison-Wesley, 2003• Matt Zandstra Php 5 Objects, Patterns, Practice Apress, 2004
• Jason E. Sweat Php Architect's Guide to Php Design Patterns Marco Tabini & Associates, 2005