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