Archive for the ‘Design Patterns’ Category

Design Patterns Reference: Prototype

Sunday, November 28th, 2010

“In situations where a resource intensive object needs to be created often, the Prototype Pattern provides a welcome route to faster execution.”

 

“The Prototype Design Pattern creates objects in such a way that an initial object or prototype can be copied and cloned more efficiently than creating a new instance.”

 

class CD
{
public $band = ”;
public $title = ”;
public $trackList = array();

public function __construct($id)
{
$handle = mysql_connect(‘localhost’, ‘user’, ‘pass’);
mysql_select_db(‘CD’, $handle);

$query = “select band, title, from CDs where id={$id}”;

$results = mysql_query($query, $handle);

if ($row = mysql_fetch_assoc($results)){
$this->band = $row['band'];
$this->title = $row['title'];
}
}

 

public function buy()
{
// cd buying magic here
var_dump ($this);
}
}

 

class MixtapeCD extends CD
{
public function __close()
{
$this->title = ‘Mixtape’;
}
}

 

$externalPurchaseInfoBandID = 12;
$bandMixProto = new MixtapeCD($externalPurchaseInfoBandID);

 

$externalPurchaseInfo = array();
$externalPurchaseInfo[] = array(‘brrr’, ‘goodbye’);
$externalPurchaseInfo[] = array(‘what it means’, ‘brrr’);

 

foreach ($externalPurchaseInfo as $mixed) {
$cd = clone $bandMixProto;
$cd->trackList = $mixed;
$cd->buy();
}

 

“When working with objects whose creation is expensive and whose initial configuration stays relatively the same through new instances, using duplicate classes made with the Prototype Design Pattern is best practice.”

 

source: http://www.wiley.com/WileyCDA/WileyTitle/productCd-0470496703,descCd-DOWNLOAD.html

 

 

Design Patterns Reference: Observer

Sunday, November 14th, 2010

The Observer Design Pattern facilitates the creation of objects that watch the state of a target object and provides state targeted functionality that is uncoupled from the core object.

The most obvious example, applications that support some type of plugin system.  Another example, cache systems, or message notification (example, members are notified when an item is in stock, to add that members may also be notified when it’s out of stock, simply add another observer, or perhaps another that texts them rather than emailing them…and so on).

When adding features to software that are activated by an action or state change but are loosely coupled, objects based on the Observer Design Pattern should be created.

MyObject is the Observable object.  It contains a protected array of observers. A public method addObserver() takes an instance of an observer and stores it in the array.

A public method doSomething() applies a state change to MyObject, whose notify() public method then loops through the array of observers.

Each such MyObjectObserver has a public method change(), that accepts an instance of MyObject, which modifies said object via a notify() method of MyObject that calls MyObjectObserver’s change() method directly as it’s encountered in the array of observers.

class CD
{
public $title = ”;
public $band = ”;
protected $_observers = array();

public function __construct($title, $band)
{
$this->title = $title;
$this->band = $band;
}

public function attachObserver($type, $observer)
{
$this->_observers[$type][] = $observer;
}

public function notifyObserver($type)
{
if(isset($this->_observers[$type])){
foreach($this->_observers[$type] as $observer)
{
$observer->update($this);
}
}
}

public function buy()
{
// stub actions of buying
$this->notifyObserver(‘purchased’);
}
}

class buyCDNotifyStreamObserver
{
public function update(CD $cd)
{
$activity = “The CD named {$cd->title} by “;
$activity .= “{$cd->band} was just purchased.”;
activityStream::addNewItem($activity);
}
}

class activityStream
{
public static function addNewItem($item)
{
// stub functions
print $item;
}
}

$title = “Wast of a Rib”;
$band = ‘Never Again’;
$cd = new CD($title, $band);

$observer = new buyCDNotifyStreamOberver();
$cd->attachObserver(‘purchased’, $observer);
$cd->buy();

source: http://www.wiley.com/WileyCDA/WileyTitle/productCd-0470496703,descCd-DOWNLOAD.html

Design Patterns Reference: Mediator

Saturday, October 30th, 2010

The Mediator Design Pattern is used to develop an object that communicates or mediates changes to a collection of similar objects without them interacting with each other directly.
class CD
{
public $band = ”;
public $title = ”;
protected $_mediator;

public function __construct($mediator = null)
{
$this->_mediator = $mediator;
}

public function save()
{
// stub – writes data back to database – use this to verify
var_dump($this);
}

public function changeBandName($newName)
{
$this->band = $newName;
$this->save();
}
}

class MP3Archive
{
public $band = ”;
public $title = ”;
protected $_mediator;

public function __construct($mediator = null)
{
$this->_mediator = $mediator;
}

public function save()
{
// stub – writes data back to database – use this to verify

var_dump($this);
}

public function changeBandName($newName)
{
if (!is_null($this->_mediator)){
$this->_mediator->change($this, array(‘band’=>$newName));
}
$this->band = $newName;
$this->save();
}
}

class MusicContainerMediator
{
protected $_containers = array();

public function __construct()
{
$this->_containers[] = ‘CD’;
$this->_containers[] = ‘MP3Archive’;
}

public function change($originalObject, $newValue)
{
$title = $originalObject->title;
$band = $originalObject->band;

foreach ($this->_containers as $container){
if (!($changedObject instanceof $container)){
$object = new $container;
$object->title = $title;
$object->band = $band;

foreach ($newValue as $key=>$value){
$object->key = $val;
}

$object->save();
}
}
}
}

// To use the new Mediator object

$titleFromDB = ‘Waste of a Rib’;
$bandFromDB = ‘Never Again’;

$mediator = new MusicContainerMediator();
$cd = new CD($mediator);
$cd->title = $titleFromDB;
$cd->band = $bandFromDB;

$cd->changeBandName(‘Maybe Once More’);

source: http://www.wiley.com/WileyCDA/WileyTitle/productCd-0470496703,descCd-DOWNLOAD.html

Design Patterns Reference: Interpreter

Sunday, October 17th, 2010

“The Interpreter Design Pattern analyzes an entity for key elements and provides its own interpretation or action corresponding to each key.”
class User
{
protected $_username;

public function __construct($username)
{
$this->_username = $username;
}

public function getProfilePage()
{
// In lieu of getting the data from a DB, we mock here
$profile = “<h2>I like Never Again!</h2>”;
$profile .= “I love all of their songs. My favorite CD:<br />”;
$profile .= “{{myCD.getTitle}}!!”;

return $profile;
}
}

class userCD
{
protected $_user = NULL;

public function setUser($user)
{
$this->_user = $user;
}

public function getTitle()
{
// mock here
$title = “Waste of a Rib”;

return $title;
}
}

class userCDInterpreter
{
protected $_user = NULL;

public function setUser($user)
{
$this->_user = $user;
}

public function getInterpreted()
{
$profile = $this->_user->getProfilePage();

if (preg_match_all(‘/\{\{myCD\.(.*?)\}\}/’, $profile, $triggers, PREG_SET_ORDER)){
$replacements = array();

foreach($triggers as $trigger){
$replacements[] = $trigger[1];
}
$replacements = array_unique($replacements);
$myCD = new userCD();
$myCD->setUser($this->_user);
foreach($replacements as $replacement){
$profile = str_replace(“{{myCD.{$replacement}}}”, call_user_func(array($myCD, $replacement)), $profile);
}
}
return $profile;
}
}

/**
* implementation
*/

$username = ‘aaron’;
$user = new User($username);
$interpreter = new userCDInterpreter();
$interpreter->setUser($user);
print “<h1>{$username}’s Profile</h1>”;
print $interpreter->getInterpreted();

source: http://www.wiley.com/WileyCDA/WileyTitle/productCd-0470496703,descCd-DOWNLOAD.html

Design Patterns Reference: Factory

Sunday, October 17th, 2010

“The Factory Design Pattern provides a simple interface to acquire a new instance of an object, while sheltering the calling code from the steps to determine which base class is actually instantiated.”
class standardCD
{
public $title = “”;
public $band = “”;
public $tracks = array();

public function __construct()
{
//
}

public function setTitle($title)
{
$this->title = $title;
}

public function setBand($band)
{
$this->band = $band;
}

public function addTrack($track)
{
$this->tracks[] = $track;
}
}

/**
* create a complete standardCD object
*/

$title = ‘Waste of a Rib’;
$band = ‘Never Again’;
$tracksFromExternalSource = array(‘What It Means’,'Brrr’,'Goodbye’);
$cd = new CD();
$cd->setTitle($title);
$cd->setBand($band);
foreach ($tracksFromExternalSource as $track)
{
$cd->addTrack($track);
}

/**
* another slight variation of a CD
* ‘enhanced’ is required as well
*/

class enhancedCD
{
public $title = “”;
public $band = “”;
public $tracks = array();

public function __construct()
{
//
}

public function setTitle($title)
{
$this->title = $title;
}

public function setBand($band)
{
$this->band = $band;
}

public function addTrack($track)
{
$this->tracks[] = ‘DATA TRACK’;
}
}

/**
* We could use conditional logic
* to determine which class to instantiate
* standardCD or enhancedCD
* but behold, instead, the Factory Pattern!
*/

class CDFactory
{
public static function create($type)
{
$class = strtolower($type) . “CD”;
return new $class;
}
}

/**
* Thus, to create a CD or an enhancedCD
*/

$type = ‘enhanced’; // or $type = ‘standard’;
$cd = CDFActory::create($type);
$cd->setBand($band);
$cd->setTitle($title);
foreach($tracksFromExternalSource as $track)
{
$cd->addTrack($track);
}

source: http://www.wiley.com/WileyCDA/WileyTitle/productCd-0470496703,descCd-DOWNLOAD.html