Archive for the ‘Design Patterns’ Category

Design Patterns Reference: Visitor

Monday, January 3rd, 2011

“The Visitor Design Pattern constructs distinct objects containing an algorithm that, when consumed by a parent object in a standard way, apply that algorithm to the parent object.”

 

class CD
{
public $band;
public $title;
public $price;

 

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

 

public function buy()
{
// stub
}

 

public function acceptVisitor($visitor)
{
$visitor->visitCD($this);
}
}

 

class CDVisitorLogPurchase
{
public function visitCD($cd)
{
$logline = “{$cd->title} by {$cd->band} was purchased for {$cd->price} “;
$logline .= “at ” . sdate(‘r’) . “\n”;

 

file_put_contents(‘/logs/purchases.log’, $logline, FILE_APPEND);
}
}

 

// usage
$externalBand = ‘Never Again’;
$externalTitle = ‘Waste of a Rib’;
$externalPrice = 9.99;

 

$cd = new CD($externalBand, $externalTitle, $externalPrice);
$cd->buy();
$cd->acceptVisitor(new CDVisitorLogPurchase());

 

// adding a new Visitor to accomplish a new functionality is straight forward
class CDVisitorPopulateDiscountList
{
public function visitCD($cd)
{
if ($cd->price < 10)
{
$this->_populateDiscountList($cd);
}
}

 

protected function _populateDiscountList($cd)
{
// stub connects to sqlite and logs etc…
}
}

 

// again, usage
$cd = new CD($externalBand, $externalTitle, $externalPrice);
$cd->buy();
$cd->acceptVisitor(new CDVisitorLogPurchase());
$cd->acceptVisitor(new CDVisitorPopulateDiscountList());

 

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

 

 

Design Patterns Reference: Template

Thursday, December 30th, 2010

“The Template Design Pattern creates an abstract object that enforces a set of methods and functionality that will be used in common by child classes as a template for their own design.”

 

abstract class SaleItemTemplate
{
public $price = 0;

 

public final function setPriceAdjustments()
{
$this->price += $this->taxAddition();
$this->price += $this->oversizedAddition();
}

 

protected function oversizedAddition()
{
return 0;
}

 

abstract protected function taxAddition();
}

 

class CD extends SaleItemTemplate
{
public $band;
public $title;

 

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

 

protected function taxAddition()
{
return round($this->price * .05, 2);
}
}

 

class BandEndorsedCaseOfCerial extends SaleItemTemplate
{
public $band;

 

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

 

protected function taxAddition()
{
return 0;
}

 

protected function oversizedAddition()
{
return round($this->price * .20, 2);
}
}

 

// use
$externalTitle = “Waste of a Rib”;
$externalBand = “Never Again”;
$externalCDPrice = 12.99;
$externalCerealPrice = 90;
$cd = new CD($externalBand, $exteralTitle, $externalCDPrice);
$cd->setPriceAdjustments();

 

print ‘The total cost for CD item is: $’ . $cd->price;

 

$cereal = new BandEndorsedCaseOfCerial($externalBand, $externalCerealPrice);
$cereal->setPriceAdjustments();

 

print ‘The total cost for the Cereal case is: $’ . $cereal->price;

 

“When creating an object where the general steps of a design are defined but the actual logic is left to be detailed by a child class, using the Template Design Pattern is best practice.”

 

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

 

 

Design Patterns Reference: Strategy

Wednesday, December 29th, 2010

“The Strategy Design Pattern helps architect an object that can make use of algorithms in other objects on demand in lieu of containing the logic itself.”

 

class CDusesStrategy
{
public $title = ”;
public $band = ”;

 

protected $_strategy;

 

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

 

public function setStrategyContext($strategyObject)
{
$this->_strategy = $strategyObject;
}

 

public function get()
{
return $this->_strategy->get($this);
}
}

 

class CDAsXMLStrategy
{
public function get(CDusesStrategy $cd)
{
$doc = new DomDocument();
$root = $doc->createElement(‘CD’);
$root = $doc->appendChild($root);
$title = $doc->createElement(‘TITLE’, $cd->title);
$title = $root->appendChild($title);
$band = $root->createElement(‘BAND’, $cd->band);
$band = $root->appendChild($band);

 

return $doc->saveXML();
}
}

 

class CDAsJSONStrategy
{
public function get(CDusesStrategy $cd)
{
$json = array();
$json[‘CD’][‘title’] = $cd->title;
$json[‘CD’][‘band’] = $cd->band;

 

return json_encode($json);
}
}

 

// usage
$cd = new CDusesStrategy($externalTitle, $externalBand);

 

// xml output
$cd->setStrategyContext(new CDAsXMLStrategy());
print $cd->get();

 

// json output
$cd->setStrategyContext(new CDAsJSONStrategy());
print $cd->get($cd);

 

“When it’s possible to create interchangeable objects made of self-contained algorithms to be applied to a base object, it is best practice to use the Strategy Design Pattern”

 

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

 

 

Design Patterns Reference: Singleton

Wednesday, December 8th, 2010

“The singleton Design Pattern is used to restrict the number of times a specific object can be created to a single time by providing access to a shared instance of itself.”

 

“The constructor of the object should be a protected method. This will not allow anything but the class itself to create an instance of it. Then it can make a public method to actually create, store, and provide that instance.”

 

Most common use: database connection

 

More interesting possible use, food for thought: configuration option management…

 

class InventoryConnection
{
protected static $_instance = NULL;
protected $_handle = NULL;
public static function getInstance()
{
if(!self::$_instance instanceof self){
self::$_instance = new self;
}
return self::$_instance;
}

 

protected function __construct()
{
$this->_handle = mysql_connect(‘localhost’,’user’,’pass’);
mysql_select_db(‘CD’, $this->_handle);
}

 

public function updateQuantity($band, $title, $number)
{
$query = “update CDS set amount = amount+” . intval($number);
$query .= ” where band=‘ ” . mysql_real_escape_string($band) . ” ‘ “;
$query .= ” and title=‘ ” . mysql_real_escape_string($title) . ” ‘ “;
mysql_query($query, $this->_handle);
}
}

 

class CD
{
protected $_title = ‘ ‘;
protected $_band = ‘ ‘;
public function __construct($title, $band)
{
$this->_title = $title;
$this->_band = $band;
}

 

public function buy()
{
$inventory = InventoryConnection::getInstance();
$inventory->updateQuantity($this->_band, $this->_title, -1);
}
}

 

$boughtCDs = array();
$boughtCDs[] = array(‘band’=>’Never Again’, ‘Waste of a Rib’);
$boughtCDs[] = array(‘band’=>’Therapee’, ‘Long Road’);

 

foreach($boughtCDs as $boughtCD){
$cd = new CD($boughtCD[‘title’], $boughtCD[‘band’]);
$cd->buy();

 

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

 

 

Design Patterns Reference: Proxy

Monday, November 29th, 2010

The Proxy Design Pattern buils an object that is positioned transparently within two other objects in order to intercept or proxy the communication or access.

 

class CD
{
protected $_title = ”;
protected $_band = ”;
protected $_handle = null;

 

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

 

public function buy()
{
$this->_connect();

 

$query = “update CDs set bought=1 where band='”;
$query .= mysql_real_escape_string($this->_band, $this->_handle);
$query .= “‘ and title='”;
$query .= mysql_real_escape_string($this->_title, $this->_handle);
$query .= “‘”;

 

mysql_query($query, $this->_handle);
}

 

protected function __connect()
{
$this->_handle = mysql_connect(‘localhost’, ‘user’, ‘pass’);
mysql_select_db(‘CD’, $this->_handle);
}
}

 

// CD class simply takes a band and title, updates the DB, and completes the sale
$externalTitle = “Waste of a Rib”;
$externalBand = ‘Never Again’;

 

$cd = new CD($externalTitle, $externalBand);
$cd->buy();

 

// A new store in another city will leverage this now via Proxy
// simply by overwriting the protected connect method of the CD class

class DallasNOCCDProxy extends CD
{
protected function __connect()
{
$this->_handle = mysql_connect(‘dallas’, ‘user’,’pass’);
mysql_select_db(‘CD’);
}
}

 

$externalTitle = “Waste of a Rib”;
$externalBand = ‘Never Again’;

 

$cd = new DallasNOCCDProxy($externalTitle, $externalBand);
$cd->buy();

 

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

 

 

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

Design Patterns Reference: Facade

Wednesday, October 13th, 2010

“The Facade Design Pattern hides complexity from a calling object by creating a simple facade interface in front of the collection of required logic and methods.”

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

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

/**
* build a CD
*/

$tracksFromExternalSource = array(‘What It Means’,’Brrr’,’Goodbye’);
$title = ‘Waste of a Rib’;
$band = ‘Never Again’;
$cd = new CD($title, $band, $tracksFromExternalSource);

class CDUpperCase
{
public static function makeString(CD $cd, $type)
{
$cd->$type = strtoupper($cd->$type);
}

public static function makeArray(CD $cd, $type)
{
$cd->$type = array_map(‘strtoupper’, $cd->$type);
}
}

class CDMakeXML
{
public static function create(CD $cd)
{
$doc = new DomDocument();

$root = $doc->createElement(‘CD’);
$root = $doc->appendChild($root);

$title = $doc->createElement(‘TITLE’, $cd->title);
$title = $root->appendChild($title);

$band = $doc->createElement(‘BAND’, $cd->band);
$band = $root->appendChild($band);

$tracks = $doc->createElement(‘TRACKS’);
$tracks = $root->appendChild($tracks);

foreach ($cd->tracks as $track){
$track = $doc->createElement(‘TRACK’, $track);
$track = $tracks->appendChild($track);
}
return $doc->saveXML();
}
}

/**
* instead of applying CDUpperCase & CDMake XML on CD object as follows:
*/

CDUpperCase::makeString($cd, ‘title’);
CDUpperCase::makeString($cd, ‘band’);
CDUpperCase::makeArray($cd, ‘tracks’);
print CDMakeXML::create($cd);

/**
* a facade object better serves the purpose!
*/

class WebServiceFacade
{
public static function makeXMLCall(CD $cd)
{
CDUpperCase::makeString($cd, ‘title’);
CDUpperCase::makeString($cd, ‘band’);
CDUpperCase::makeArray($cd, ‘tracks’);

$xml = CDMakeXML::create($cd);

return $xml;
}
}

/**
* thus implemented in ONE line instead, as follows:
*/

print WebServiceFacade::makeXMLCall($cd);

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

Design Patterns Reference: Delegate

Tuesday, October 12th, 2010

“The Delegate Design Pattern removes decisions and complex functionality from the core object by distributing or delegating them to other objects.”

This example accomplishes this by utilizing PHP’s ability to dynamically create class instances based on a variable, and thus functionality may be spread across multiple objects rather than managed by one conglomerated block of conditional logic.

/**
* version 1
* NON-Delegate implementation
* as you’ll see,
* could easily become unweildly
* to extend…
*/

class Playlist
{
private $__songs;

public function __construct()
{
$this->__songs = array();
}

public function addSong($location, $title)
{
$song = array(‘location’=>$location, ‘title’=>$title);
$this->__songs[] = $song;
}

public function getM3U()
{
$m3u = “#EXTM3U\n\n”;

foreach($this->__songs as $song){
$m3u .= “#EXTINF:-1,{$song[‘title’]}\n”;
$m3u .= “{$song[‘location’]}\n”;
}
return $m3u;
}

public function getPLS()
{
$pls = “\nNumberOfEntries=” . count($this->__songs) . “\n\n”;

foreach ($this->__songs as $songCount=>$song){
$counter = $songCount + 1;
$pls .= “File{$counter}={$song[‘location’]}\n”;
$pls .= “Title{$counter}={$song[‘title’]}\n”;
$pls .= “Length{$counter}=-1\n\n”;
}
return $pls;
}
}

/**
* Implemented as follows:
*/

$playlist = new Playlist();
$playlist->addSong(‘/home/aaron/music/brr.mp3’, ‘Brr’);
$playlist->addSong(‘/home/aaron/music/goodbye.mp3’, ‘Goodbye’);
if($externalRetrievedType == ‘pls’){
$playlistContent = $playlist->getPLS();
}
else {
$playlistContent = $playlist->getM3U();
}

/**
* version 2
* Delegate Design Pattern implementation
*/

class newPlaylist
{
private $__songs;
private $__typeObject;

public function __construct($type)
{
$this->__songs = array();
$object = “{$type}PlaylistDelegate”;
$this->__typeObject = new $object;
}

public function addSong($location, $title)
{
$song = array(‘location’=>$location, ‘title’=>$title);
$this->__songs[] = $song;
}

public function getPlaylist()
{
$playlist = $this->__typeObject->getPlaylist($this->__songs);
return $playlist;
}
}

class m3uPlaylistDelegate
{
public function getPlaylist($songs)
{
$m3u = “#EXTM3U\n\n”;

foreach ($songs as $song){
$m3u .= “EXTINF:-1,{$song[‘title’]}\n”;
$m3u .= “{$song[‘location’]}\n”;
}
return $m3u;
}
}

class plsPlaylistDelegate
{
public function getPlaylist($songs)
{
$pls = “\nNumberOfEntries=” . count($songs) . “\n\n”;

foreach($songs as $songCount=>$song){
$counter = $songCount + 1;
$pls .= “File{$counter}={$song[‘location’]}\n”;
$pls .= “Title{$counter}={$song[‘title’]}\n”;
$pls .= “Length{$counter}=-1\n\n”;
}
return $pls;
}
}

/**
* Implemented as follows:
*/

$externalRetrievedType = ‘pls’;
$playlist = new newPlaylist($externalRetrievedType);
$playlistContent = $playlist->getPlaylist();

// to see results of course, something like:

print_r($playlistContent);

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

Design Patterns Reference: Decorator

Tuesday, October 12th, 2010

“The Decorator Design Pattern is best suited for altering or decorating portions of an existing object’s content or functionality without modifying the structure of the original object.”

class CD
{
public $trackList;

public function __construct()
{
$this->trackList = array();
}

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

public function getTrackList()
{
$output = “”;

foreach ($this->trackList as $num=>$track){
$output .= ($num + 1) . “) {$track}. “;
}
}
}

/**
* cd object use
*/

$tracksFromExternalSource = array(‘What It Means’, ‘Brr’, ‘Goodbye’);
$myCD = new CD();
foreach ($trackFromExternalSource as $track){
$myCD->addTrack($track);
}
print “The CD contains the following tracks: ” . $myCD->getTrackList;

/**
* aha, but now the requirements change on us…
* now all tracks need to display uppercase!
* Instead of modifying the original class,
* or changing the parent-child relationships for such small “living requirements”…
* we use the Decorator design pattern!
*/

class CDTrackListDecoratorCaps
{
private $__cd;

public function __construct(CD $cd)
{
$this->__cd = $cd;
}

public function makeCaps()
{
foreach ($this->__cd->trackList as &$track)
{
$track = strtoupper($track);
}
}
}

/**
* new object use
*/

$myCD = new CD();
foreach ($tracksFromExternalSource as $track){
$myCD->addTrack($track);
}
$myCDCaps = new CDTrackListDecoratorCaps($myCD);
$myCDCaps->makeCaps();

print “The CD contains the following tracks: ” . $myCD->getTrackList();

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

Design Patterns Reference: Data Access Object DAO

Tuesday, October 12th, 2010

“The Data Access Object Design Pattern describes the creation of an object that provides transparent access to any data source.”

/**
* Data Access Object Pattern Example
*/

/**
* first we define the abstract base DAO class,
* which, of course, thus MUST be extended to be used
* to note:
* – the connection is internally referenced,
* allowing multiple simultaneous connections and tables
* – the fetch and update methods are wonderfully abstract
* untied to table name, key, or value
*/
abstract class baseDAO
{
private $__connection;

public function __construct()
{
$this->__connectToDB(DB_USER, DB_PASS, DB_HOST, DB_DATABASE);
}

public function fetch($value, $key = NULL)
{
if (is_null($key)){
$key = $this->_primaryKey;
}

$sql = “select * from {$this->_tableName} where {$key}='{$value}'”;
$results = mysql_query($sql, $this->__connection);

$rows = array();
while ($result = mysql_fetch_array($results)){
$rows[] = $result;
}

return $rows;
}

public function update($keyedArray)
{
$sql = “update {$this->_tableName} set “;

$updates = array();
foreach ($keyedArray as $column=>$value){
$updates[] = “{$column}='{$value}'”;
}

$sql .= implode(‘,’, $updates);
$sql .= “where {$this->_primaryKey}='{$keyedArray[$this->_primaryKey]}'”;

mysql_query($sql, $this->__connection);
}
}

/**
* Finally, let’s extend with a child class
* mapped to a specific table
*/

class userDAO extends baseDAO
{
protected $_tableName = ‘userTable’;
protected $_primaryKey = ‘id’;

public function getUserByFirstName($name)
{
$result = $this->fetch($name, ‘firstName’);
return result;
}
}

/**
* Example of use
* DB connect data, of course, would be elsewhere and flexible
*/

define(‘DB_USER’,’user’);
define(‘DB_PASS’,’pass’);
define(‘DB_HOST’,’localhost’);
define(‘DB_DATABASE’,’test’);

/** fetch row id 1 **/
$user = new userDAO();
$userDetailsArray = $user->fetch(1);

/** update row id 1 **/
$updates = array(‘id’=>1, ‘firstName’=>’aaron’);
$user->update($updates);

/** get users with first name aaron **/
$allAarons = $user->getUserByFirstName(‘aaron’);

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

Design Patterns Reference: Builder

Tuesday, October 12th, 2010

“The Builder Design Pattern defines the design of an object that handles the complex building of another object.”

/**
* the Builder Pattern
* creates objects
* so that only its build method need be modified
* if the class it builds changes in the future
* and to automate object instantiation according to requirements
*/

/**
* class that could change with time
*/

class product
{
protected $_type = ”;
protected $_size = ”;
protected $_color = ”;

public function setType($type)
{
$this->_type = $type;
}

public function setSize($size)
{
$this->_size = $size;
}

public function setColor($color)
{
$this->_color = $color;
}
}

/**
* thus, rather than implementing each and every
* instantiation of the product class as follows:
*/

$productConfigs = array(‘type’=>’shirt’,’size’=>’XL’,’color’=>’red’);
$product = new product();
$product->setType($productConfigs[‘type’]);
$product->setSize($productConfigs[‘size’]);
$product->setColor($productConfigs[‘color’]);

/**
* and then having to change every instantiation
* if/when the product class changes!
* instead, we create a productBuilder,
* and then the change simply happens in the product class
* and in the builder build method
*/

class productBuilder
{
protected $_product = NULL;
protected $_xml = array();

public function __construct($configs)
{
$this->_product = new product();
$this->_xml = $configs;
}

public function build()
{
$this->_product->setSize($configs[‘size’]);
$this->_product->setType($configs[‘type’]);
$this->_product->setColor($configs[‘color’]);
}

public function getProduct()
{
return $this->_product;
}
}

/**
* implemented, instead as follows:
*/

$builder = new productBuilder($productConfigs);
$builder->build();
$product = $builder->getProduct();

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

Design Patterns Reference: Adapter

Tuesday, October 12th, 2010

“The Adapter Design Pattern simply adapts one object’s interfaces to what another object expects.”

/**
* Example Adapter Class
*/

/**
* original object
*/

class errorObject
{
private $__error;

public function __construct($error)
{
$this->__error  = $error;
}

public function getError()
{
return $this->__error;
}
}

/**
* original Log class
*/

class logToConsole
{
private $__errorObject;

public function __construct($errorObject)
{
$this->__errorObject = $errorObject;
}

public function write()
{
fwrite(STDERR, $this->__errorObject->getError());
}
}

/**
* Initial way to utilize this system
* create the new 404 error object
*/

$error = new errorObject(“404:Not Found”);

/** then write the error to the console **/

$log = new logToConsole($error);
$log->write();

/**
* extend the logging functionality
* to log to CSV file instead
* with the log # and text
*/

class logToCSV
{
const CSV_LOCATION = ‘log.csv’;

private $__errorObject;

public function __construct($errorObject)
{
$this->__errorObject = $errorObject;
}

public function write()
{
$line = $this->__errorObject->getErrorNumber();
$line .= ‘,’;
$line .= $this->__errorObject->getErrorText();
$line .= “\n”;

file_put_contents(self::CSV_LOCATION, $line, FILE_APPEND);
}
}

/**
* to use the new log
* original errorObject must either be changed
* or better, extended
*/

class logToCSVAdapter extends errorObject
{
private $__errorNumber, $__errorText;

public function __construct($error)
{
parent::__construct($error);

$parts = explode(‘:’, $this->getError());

$this->__errorNumber = $parts[0];
$this->__errorText = $parts[1];
}

public function getErrorNumber()
{
return $this->__errorNumber;
}

public function getErrorText()
{
return $this->__errorText;
}
}

/**
* new way to implement the system extended
* create the new 404 error object adapted for csv
*/

$error = new logToCSVAdapter(“404:Not Found”);

/** then write the error to the csv file **/
$log = new logToCSV($error);
$log->write();

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

Design Patterns Reference: Iterator

Tuesday, October 12th, 2010

“The Iterator Design Pattern helps construct objects that can provide a single standard interface to loop or iterate through any type of countable data.”

class  implements Iterator
{
/**
* Get the current element
* @return mixed
*/

public function current()
{
}

/**
* Gets the current key
* @return mixed
*/

public function key()
{
}

/**
* Checks if current element exists
* @return boolean
*/

public function valid()
{
}

/**
* Moves pointer forward to next element
*/

public function next()
{
}

/**
* Moves pointer to first element
*/

public function rewind()
{
}
}

/**

* Example Implementation

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

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

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

/**
* SPL Iterator, thus requires:
* current(), key(), rewind(), next(), valid()
* public methods
*/

class CDSearchByBandIterator implements Iterator
{
private $__CDs = array();
private $__valid = FALSE;

public function __construct($bandName)
{
$db = mysql_connect(‘localhost’,’user’,’pass’);
mysql_select_db(‘test’);
$sql = “select CD.id, CD.band, CD.title, tracks.tracknum, “;
$sql .= “tracks.title as tracktitle “;
$sql .= “from CD left join tracks on CD.id = tracks.cid where band='”;
$sql .= mysql_real_escape_string($bandname);
$sql .= “‘ order by tracks.tracknum”;
$results = mysql_query($sql);

$cdID = 0;
$cd = NULL;

while($result = mysql_fetch_array($results)){
if($result[‘id’] !== $cdID){
if (!is_null($cd)){
$this->__CDs[] = $cd;
}
$cdID = $result[‘id’];
$cd = new CD($result[‘band’], $result[‘title’]);
}
$cd->addTrack($result[‘tracktitle’]);
}
$this->__CDs[] = $cd;
}

public function next()
{
$this->__valid = (next($this->__CDs) === FALSE) ? FALSE : TRUE;
}

public function rewind()
{
$this->__valid = (reset($this->__CDs) === FALSE) ? FALSE : TRUE;
}

public function valid()
{
return $this->__valid;
}

public function current()
{
return current($this->__CDs);
}

public function key()
{
return key($this->__CDs);
}
}
/**
* Implementation
*/

$queryItem = ‘Never Again’; // band Name
$cds = new CDSearchByBandIterator($queryItem);
print ‘<h1>Found the Following CDs</h1>’;
print ‘<table><tr><th>Band</th><th>Title</th><th>Num Tracks</th></tr>’;
foreach ($cds as $cd){
print “<tr><td>{$cd->band}</td><td>{$cd->title}</td><td>”;
print count($cd->trackList) . ‘</td></tr>’;
}
print ‘</table>’;

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