Diving in Sai Kung Issue & Gap Analysis Andries Temme Susan Voelkl.
Everyday Design Patterns Andries Seutensx
-
Upload
andriesss -
Category
Technology
-
view
2.608 -
download
2
description
Transcript of Everyday Design Patterns Andries Seutensx
Andries SeutensPHP Software Engineer,Sanmax Consultancy
SME Zend Framework,Zend Technologies http://sanmax.be
http://twitter.com/[email protected]
Introduction to design patterns
What are they What are they not Where to use them
Common design patterns
Solutions to recurring design problems
Common language “Hey, let's use a factory pattern for
this?!”
Help to understand frameworks
Pattern name
Problem description
Solution
Consequences
Silver bullet patternWill solve any programming problem
Magic code factory patternCreates exactly the code you need for the problem by magic
Library code
Full blown solutions
Deal with object creational mechanisms
Create objects in a matter suitable to the situation
We will look at 3 creational design patterns Factory Singleton Registry
Problem Avoid tight coupling Concrete instantiation
Characteristics Common in toolkits and
frameworks Avoids dependency
Avoid copy / paste programming
Eases maintenance
Most common are database classes
$db = Zend_Db::factory('Pdo_Mysql', array( 'host' => '127.0.0.1', 'username' => 'webuser', 'password' => 'xxxxxxxx', 'dbname' => 'test'));
$db = Zend_Db::factory('Pdo_Oracle', array( 'host' => '127.0.0.1', 'username' => 'webuser', 'password' => 'xxxxxxxx', 'dbname' => 'test'));
Problem We need an application wide instance Require an exclusive resource
Characteristics Ensures a class only has one instance Provides a global point of access to it
class Singleton{
private static $_instance;
private function __construct() {}private function __clone() {}
public static function getInstance() {if (!self::$_instance instanceof self) {
self::$_instance = new self();}return self::$_instance;
}}
// Use case$foo = Singleton::getInstance();
Problem Global meltdown
Characteristics Can be used to find common objects Centers around PHP’s arrays
$config = new Zend_Config_Ini('my.ini', 'production');
// store config in registryZend_Registry::set('config', $config);
// somewhere else in your codebaseZend_Registry::get('config')->smtp->servername;
Ease design by identifying simple ways to realize relationships between classes
We will look at 3 structural design patterns:
Data Mapper Decorator Adapter
Problem Object schema and the relational
schema don't match up
Characteristics Separates objects from the database
class UserMapper{
public function save(User $user) {$data = array(
'username' => $user->getUsername(),'password' => sha1($user->getPassword()),
);$table = $this->getTable();$table->save($data);$user->setId($table->lastInsertId());
}public function getTable() {}
}
Problem Overuse of inheritance Multiple inheritance
Characteristics Allows new/additional behavior An alternative to subclassing
class CachingUserMapper{ $this->_mapper; public function __construct(UserMapper $mapper) { $this->_mapper = $mapper; } public function fetch($username) { $cache = $this->getCache(); if (($person = $cache->load($username)) === false) { $person = $this->_mapper->fetch($username); $cache->save($person, $username); } return $person; }}
Problem Convert an object of one type to an object of another typeHave multiple libraries use the same interface
CharacteristicsWraps to translate object into another interfaceAllows classes to work together
Increase flexibility and extensibility
We will look at these 2 behavioral patterns:
Strategy Observer
Problem Dynamically swap the algorithms used
Characteristics Defines a family of algorithms Unified API for use with various
backends
class UserList{ protected $_strategy; protected $_users; public function addUser($username) { $this->_users[] = $username; return $this; } public function sort(SortStrategy $strategy) { return $strategy->sort($this->_users); }}
abstract class SortStrategy{ abstract public function sort(Array $data);}
class AscendingSort extends SortStrategy{ public function sort(Array $data) { asort($data); return $data; }}
class DescendingSort extends SortStrategy{ public function sort(Array $data) { arsort($data); return $data; }}
$list = new UserList();$list->addUser('DragonBe');$list->addUser('Inventis');$list->addUser('Sanmax');
$ascending = $list->sort(new AscendingSort());$descending = $list->sort(new DescendingSort());
Problem Need to be able to notify and update dependents programatically when object's state changesEvent-driven programming at the scope of the application code
CharacteristicsNotifies observers on a state change
class ForumPost implements SplSubject{ protected $_observers = array(); protected $_content;
public function __construct($content) { $this->_content = $content; }
public function attach(SplObserver $observer) { $this->_observers[] = $observer; return $this; }
public function detach(SplObserver $observer) {}
public function notify() { foreach ($this->_observers as $obs) { $obs->update($this); } }
public function save() { $this->notify(); return $this; }}
class PostMailer implements SplObserver{ public function update(SplSubject $subject) { echo "emailing subscribed users\n"; }}
class PostFeedUpdater implements SplObserver{ public function update(SplSubject $subject) { echo "updating RSS feed\n"; }}
$post = new ForumPost('this is a new forum post');$post->attach(new PostMailer()) ->attach(new PostFeedUpdater()) ->save();
Deal with multi-threaded programmingParadigm.
Simply put .... forget it