5/29/2008

Value Object [DDD]

This metaphor does not fit completely, and the "Money-Example" is omnipresent, but I really like the pattern and so that's the story:

Let's say you have your grannies recipe for a chocolate cookie and you want to keep this in mind, but also you like to somehow experiment with some new or different ingredients. Normally you just keep in mind what you changed and later you write down the new recipe. But from time to time you might want to compare the two recipes or maybe you want to make cookies with the new and the changed recipes. In this situation it's really good to have both written down on paper. ;)


In the world of OOP you could think of a solution using the Memento-Pattern but this doesn't really fit the situation and it's also some kind of overhead. That's the reason why the Value Object is the pattern of my choice.

So let's look at the recipes again - we want to add and remove ingredients without modifying the original recipe and we want to compare the resulting recipes. We don't need to track a special identity of our recipes since we're only "collecting" ingredients.

The idea of the Value Object is that every
every method which somehow transforms the state of a object always returns a new object and the old object stays untouched. Whenever needed you should also implement a method to compare objects, I must concede that the common "Money Example" shows much better when that's needed ...

Another edge of this pattern in PHP is that you can use method-chaining to perform multiple actions within a single line of code. So just have a look at the example you will like it's taste :)

Show PHP Source Code




class
Recipe {
protected
$ingredients;

public function
__construct($ingred='') {
$this->ingredients = implode(',',array_unique(explode(',',$ingred)));
}

public function
addIncredient($ingred='') {
return new
Recipe($this->ingredients.','.$ingred);
}

public function
removeIncredien($ingred='') {
return new
Recipe(preg_replace('/,{0,1}'.$ingred.',{0,1}/','',$this->ingredients.','));
}

public function
printIncredients() {
echo
str_replace(',','<br/>',$this->ingredients);
}

public function
equals(Recipe $recipe) {
return (
strcmp($this->ingredients,$recipe->ingredients)===0)?true:false;
}
}


Show PHP Client Code


$granniesRecipe = new Recipe('flour,baking soda,sugar,salt,butter,vanilla,chocolate');
$aNewRecipe = $granniesRecipe->addIncredient('lemon');
$coconutRecipe = $granniesRecipe->removeIncredien('chocolate')->addIncredient('coconut');

// check if that worked:
echo '<br/><strong> Grannies Cookie Recipe - Incredients are:</strong><br/>';
$granniesRecipe->printIncredients();
echo
'<br/><strong> A new Cookie Recipe could look like:</strong><br/>';
$aNewRecipe->printIncredients();
echo
'<br/><strong> A coconut cookie would look like:</strong><br/>';
$coconutRecipe->printIncredients();



The implementation is a bit odd, since it only collects the names of the ingredients but not the amount, but including the amounts of incredients would not change the concept and that's why I left it out. I hope you got a idea how the pattern works - the main thing is that there's no identity and that new objects are instantiated as soon as the state of the old one would change.

5/27/2008

Prototype [GoF]

Imagine a cookie-oven which produces tasty cookies with chocolate crumbles. How do you ensure that the 1000th cookie still has the same taste as the first?
You might think that this is an easy task - just write down the recipe and follow the described steps...you know the result in real life - the 1000th cookie normally tasts like the 1st but you always had the "overhead" to read the recipe and go through the steps again and again.
In OOP it's much easier to follow the recipe just instantiate a new Object and there you go... no matter if it's the 1st or the 1000th - it'll always taste look similar.
But the "recipe-overhead" is still there in a way and especially when you have larger objects whose construction is time-consuming you might want to somehow get rid of it. And that's where a Prototype can help you out - you just create the first Cookie Object and then you use the handy magic method __clone to create new objects.
Instead of just using __clone the pattern suggests a class (some kind of a factory-class) so that you can also encapsulate the creation of the objects (and also possible adjustments you might want to make after the creation/clone).

So the example just shows a cookie-machine which makes use of the prototype-pattern to create new cookies (depending on the cookie you throw in before)... yummy



Show PHP Source Code



abstract class Cookie {
function
__clone() { }
abstract public function
printFlavor();
}

class
CoconutCookie extends Cookie {
public function
printFlavor() {
echo
'Coconut Flavor<br/>';
}
}
class
ChocolateCookie extends Cookie {
public function
printFlavor() {
echo
'Chocolate Flavor<br/>';
}
}

class
CookieMachine {
protected
$cookie;
public function
__construct(Cookie $cookie) {
$this->cookie = $cookie;
}
public function
makeCookie() {
return clone
$this->cookie;
}
}





The client-code can look like this:
Show PHP Sample Code


$coconutCookie = new CoconutCookie();
$coconutCookieMachine = new CookieMachine($coconutCookie);

$chocolateCookie = new ChocolateCookie();
$chocolateCookieMachine = new CookieMachine($chocolateCookie);

//while(true) {
for($i=0;$i<5;$i++) {
$coconutCookieMachine->makeCookie()->printFlavor();
$chocolateCookieMachine->makeCookie()->printFlavor();
}



5/24/2008

PHP FastCGI vs. PHP as a module

The apachelounge.org guy published a very interesting stat which compares the memory-usage of PHP/FastCGI and PHP/as module and that's really interesting:



There's no comment about performance and in early versions FastCGI/PHP was a bottleneck but maybe these days are gone :)

5/23/2008

Singelton [GoF]

So this pattern is a very well know and a often discussed one.

Explaining it the tasty way: let's say you have exactly one well know place where you store all your cookies and whenever you need one you can easy point to that place. Normally that's really comfortable because whatever you do with it, you don't have to search some place where you can find a cookie, you just go to that single "cookie tin" (or wherever you store cookies) and put a new cookie into it ;)

In modern OOP the singleton is not very popular, Eric Evans simple calls it anti-pattern. It makes it much harder to test your software and normally the user of the class, not the class itself, should know how many instances are needed.

But nevertheless for small applications it's very comfortable to use it in some situations and as long as you're also familiar with the drawbacks I think it's ok to consider using it....

So the example shows a cookie tin and how to use it and by the way it also implements some kind of lowlevel registry by using the PHP5 magic methods, but that's another story ;)
Show PHP Source Code



/**
* CookieTin a.k.a Singleton object
* we what to force our application

* to hold exactly one CookieTin object
*
*/
class CookieTin {
private
$_cookies=array();

/* generic singleton part start*/

private static $_instance=NULL;
// prevent instatiation from the outside
private function __construct() { }

// prevent cloning
private function __clone() {}

public static function
getInstance() {
if(!
self::$_instance) {

self::$_instance = new self();
}
return
self::$_instance;
}
/* generic singleton part end */


/* registry part start */
public static function __set($key,Cookie $value) {

echo
"call setter\n";
self::$_instance->_cookies[$key] = $value;
}


public static function
__get($key) {
echo
"call getter\n";
return
self::$_instance->_cookies[$key];

}

public static function
__isset($key) {
echo
"call isset\n";
return isset(
self::$_instance->_cookies[$key]);

}

public static function
__unset($key) {
echo
"call unset\n";
unset(
self::$_instance->_cookies[$key]);

}
/* registry part end */
}
/**
* Dummy Cookie
*/
class Cookie {
public
$name,$flavor;

}



Show PHP Client Code

$tin = CookieTin::getInstance();
if(!isset(
$tin->granniescookie)) {
$tin->granniescookie = new Cookie();

$tin->granniescookie->name="Grannies chocolate wonder";
$tin->granniescookie->flavor="chocolate";

}


CookieTin::getInstance()->granniescookie->flavor = "chocolte chips";

var_dump($tin);
unset(
CookieTin::getInstance()->granniescookie);
var_dump($tin);



The really important things happen in the last lines where the CookieTin is accessed statically and this change also (as you will see yourself) is reflected in the local instance if the $tin.

5/21/2008

PHP sucks? not really!

There are so many people from outside of the PHP World and lots of them are complaining about PHP and their reasons are mostly so ridiculous. In most cases they just say that PHP code sucks.
The PHP 10.0 Blog brought up some good arguments about that and I fully agree - it's not the language that produces sucking code, it's the guy who wrote it down. Click

5/20/2008

error_reposting and exceptions....

I just found this line:


set_error_handler(create_function('$x, $y', 'throw new Exception($y, $x);'), E_ALL~E_NOTICE);

in the comments on php.net and did a short test to see whether it works. Normally I used to have a global function which passes all the errors through a logging-chain (FILE/MAIL/DISPLAY) but having exceptions could be more comfortable because you might sometimes want to make decisions locally and not on a global scope and just setting and re-setting the error-handler is not the best idea for this... I'm not sure if I get used to it, because the error-handling function did a good job for the last years ... we'll see :)
So that's the full example code:

set_error_handler(create_function('$x, $y', 'throw new Exception($y, $x);'), E_ALL);
try {

$errors = array(
E_USER_WARNING => "something might be wrong",
E_USER_NOTICE => "it works but I don't like it",
E_USER_ERROR => "something went completly wrong",
);

// echo $name; //should cause a E_NOTICE

foreach($errors as $code=>$msg) {
try {
trigger_error($msg,$code);
}
catch (
Exception $e) {
if(!
in_array($e->getCode(),array(E_USER_WARNING,E_USER_NOTICE))) {
throw
$e;
}
else {
// not a big deal we can push this into a log-file and continue or work...
echo "local exception: (".$e->getCode(). ") ".$e->getMessage()."<br/>";
}
}
}

}
catch (
Exception $e) {
echo
"global exception:".$e->getMessage()."<br/>";
}


5/18/2008

Preview to PHP 5.3

One of the mayor updates since PHP 5.0 is upcoming with the 5.3 version, this is also a major step forward to PHP 6 - I love to have namespaces and appreciate the split of E_NOTICE and E_DEPRECATED. Also other features like the native MySQL support ( I hope this really raises the performance), the array_replace/array_replace_recursive functions and also dynamic calls to static functions "$classname::$functionname($parameter);" sound very cool. So I really look forward to have it on the server (or at least on my laptop) :P

Regarding the namespaces I've one idea: maybe someday someone will invent a common namespace "php::clean" which fixes all the small inconsistencies within function-names and parameter-styles ... that would be really great ;)

A nice article with a more detailed look into namespaces and the other inventions in 5.3 can be found on sitepoint.com

Firefox 3 RC1

I just saw that the first Release Candidate of Firefox 3 is available for download . As with the most of the Beta-versions I also checked this update because I'm really excited to get the new features, but after 5 minutes (again) I removed it from my PC. Non of my extensions is working in FF3 (except the dictionary), it still destroys the Frames in TYPO3 (there's a bugfix-extension for that) and the memory-usage is still very high,10% lower than in FF2 but still high.
So I postponed the update and kept on running Firefox 2, at least until the next Release Candidate ;)

5/17/2008

Using Mocks within Tests

Let's say you have some kind of process which creates cookies and which requires the cookies to bake before you deliver them to the customers. This process somehow touches two kinds of objects the cookie itself and a object which performs the process - the cookie oven.
When you start to develop the oven how do you check whether the cookies are really baked or not? Since you can't get rid of the dependency between the oven and the cookie, you have to simulate a real object and do the checks by hand - but wait there's already a way to resolve it:
PHPUnit ships with a very nice and comfortable function to create and check mock-objects and that's exactly what we need in this situation where we somehow need to find out if our cookie really gets baked.
The testcase for this scenario could look like this:



class
TestCookieOven extends PHPUnit_Framework_TestCase {
public function
testIfCookieIsBakenWithinFinishing() {

/* create the mock and expect the
bakeIt method to be called at least once */
$cookiemock = $this->getMock('Cookie', array('bakeIt'));
$cookiemock->expects($this->once())->method('bakeIt');

/* create the observed object and perform the required steps */
$cookieoven = new CookieOven();
$cookieoven->finishCookie($cookiemock);
}
}


This first creates a mock and assigns the expectation that the "bakeIt"-function is called exactly once. [ beside the ->once()-call there are some alternatives: ->any(), ->never(), ->atLeastOnce(), ->exactly(int $count) and ->at(int $index) ]. Then it passes the mock to the oven and performs the method we want to check. To make this test green you need at least this:


CookieOven {
/**
* Takes a cookie and prepares it to be ready
* for a customer
*
* @param Cookie $cookie
*/
public function finishCookie(Cookie $cookie) {
$cookie->bakeIt();
}
}


So as soon you have these lines you have a green test and that's great because there is no need to have a real "cookie" class - someone else can take care of the cookies - oh wait ... I'd better do this myself :P

5/15/2008

Specification [DDD]

Maybe sometimes the cookie tin is filled with all sorts of cookies and only some of them are what you'd like in this special moment. Often it's very easy to specify which cookie you like, but sometimes your wishes are very complex, for example if you look for grannies special cookie with chocolate, coconut and vanilla crumbles. This could lead into a real crumby problem if you try to sort all the cookies and then select eat the right one.

In the world of OOP it's often much harder to collect a few objects out of a large number of different objects, also combining different requirements isn't easy and that's where the specification pattern can help you out. It implements some basic operations to combine requirements (AND, OR, NOT) and the only thing a concrete specification for a concrete class has to do is to implement a method (isSatisfied()) which is able to determine whether a object meats a requirement or not.


I splitted the generic part of the script and the cookie-example. The first part just implements the methods which are needed for the combination and provides a abstract class which is extended by the specifications in the second part. As you see the specification is combined which normally encapsulates the retrieval of the objects ,for example from a database. ....just have a look it's really easy to select the right cookie ... yummy


Show PHP Source Code of the generic part

interface Specification {
public function
isSatisfiedBy($obj);
public function
_and(Specification $spec);
public function
_or(Specification $spec);
public function
_not();
}

abstract class
AbstractSpecification implements Specification {
public function
isSatisfiedBy($obj) { }
public function
_and(Specification $spec) {
return new
AndSpecification($this, $spec);
}
public function
_or(Specification $spec) {
return new
OrSpecification($this, $spec);
}
public function
_not() {
return new
NotSpecification($this);
}
}

class
AndSpecification extends AbstractSpecification {
private
$spec1, $spec2;
public function
__construct(Specification $spec1, Specification $spec2) {
$this->spec1 = $spec1;
$this->spec2 = $spec2;
}
public function
isSatisfiedBy($obj) {
return
$this->spec1->isSatisfiedBy($obj) && $this->spec2->isSatisfiedBy($obj);
}
}

class
OrSpecification extends AbstractSpecification {
private
$spec1, $spec2;
public function
__construct(Specification $spec1, Specification $spec2) {
$this->spec1 = $spec1;
$this->spec2 = $spec2;
}
public function
isSatisfiedBy($obj) {
return
$this->spec1->isSatisfiedBy($obj) || $this->spec2->isSatisfiedBy($obj);
}
}

class
NotSpecification extends AbstractSpecification {
private
$spec;
public function
__construct(Specification $spec) {
$this->spec = $spec;
}
public function
isSatisfiedBy($obj) {
return !
$this->spec->isSatisfiedBy($obj);
}
}




Show PHP Source Code of the cookie example


/**
* Cookie object just a container for the relevant data.
*
*/
class Cookie {
protected
$name,$flavor,$size;
public function
__construct($name='',$flavor='chocolate',$size=100) {
$this->name=$name;
$this->flavor = $flavor;
$this->size = abs($size); // avoid negative size
}
public function
getName() { return $this->name; }
public function
getFlavor() { return $this->flavor; }
public function
getSize() { return $this->size; }
}
/**
* Cookie service delivers cookies, offers some ways to select specific types of cookies
*
*/
class CookieService {
protected
$cookies = array();
/**
* Add a cookie to the collection
* name is used as identifier, thats not the best choice
* but it's ok for the example
*
* @param Cookie $cookie
*/
public function add(Cookie $cookie) {
$this->cookies[$cookie->getName()]=$cookie;
}
/**
* Generic method to check which objects fit the spec
*
* @param Specification $spec
*/
private function filter(Specification $spec) {
$result=array();
reset($this->cookies);
foreach(
$this->cookies as $name=>$cookie) {
if(
$spec->isSatisfiedBy($cookie)) {
$result[]=$cookie;
}
}
return
$result;
}

public function
getLargeCookies() {
$spec = new SmallCookieSpecification();
$spec = $spec->_not();
return
$this->filter($spec);
}
public function
getSmallChocolateCookies() {
$spec = new SmallCookieSpecification();
$spec = $spec->_and(new ChocolateCookieSpecification());
return
$this->filter($spec);
}
public function
loadDummyData() {
$this->add(new Cookie('Granny\'s classic','chocolate',60));
$this->add(new Cookie('Modern Jumbo','moca,chocolate',180));
$this->add(new Cookie('Kitchen Sink','macadamia,cranberrie',90));
$this->add(new Cookie('Vanilla Cloud','vanilla',120));
$this->add(new Cookie('Chocolate chip','coconut,chocolate',160));
}
}

class
SmallCookieSpecification extends AbstractSpecification {
public function
isSatisfiedBy($obj) {
return
$obj->getSize() < 100;
}
}

class
ChocolateCookieSpecification extends AbstractSpecification {
public function
isSatisfiedBy($obj) {
return
stristr(strtolower($obj->getFlavor()),'chocolate') !== FALSE;
}
}

/**
* Client code
*/
$service = new CookieService();
$service->loadDummyData();
echo
'<pre>';
var_dump($service->getLargeCookies());
var_dump($service->getSmallChocolateCookies());
echo
'</pre>';





more information by E.Evans and M.Fowler

5/13/2008

Memento [GoF]

Let's say you got a cookie from a repository your granny and you're not sure if you like the new taste. Wouldn't it be cool if you could just try it and revoke the operation first bite if you don't like it?

In the world of OOP thats a easy job which can be handled by the so called memento pattern - you just save the inner state of the object within a memento object and revoke you actions whenever you like...

As UML the example looks like this:

Show PHP Source Code


class CookieMemento {
    protected 
$flavor,$size;    
    public function 
__construct($flavor,$size=100) {
        
$this->flavor=$flavor;
        
$this->size=$size;
    }
    public function 
getMemento() {
        return new 
CookieMemento($this->flavor,$this->size);
    }
    public function 
setMemento(CookieMemento $memento) {
        
$this->flavor=$memento->flavor;
        
$this->size=$memento->size;
    }    
}

class 
Cookie extends CookieMemento {
    
    public function 
eat($reduceValue) {     
        
$this->size-=($reduceValue>$this->size)?$this->size:$reduceValue;        
    }    

    public function 
printStatus() {
        echo 
'This cookie is a '.$this->flavor.' cookie which has a size of '.$this->size.'.<br/>';
    }
}

class 
Client 
    public function 
run() {
        
$theCookie = new Cookie('chocolate',100);
        
$theMemento $theCookie->getMemento();
        echo 
$theCookie->printStatus();        
        
$theCookie->eat(50);
        echo 
$theCookie->printStatus();       
        
$theCookie->eat(50);
        echo 
$theCookie->printStatus();       
        echo 
'Hm I\'d like to eat it again .... *grin*<br/>';
        
$theCookie->setMemento($theMemento);
        echo 
$theCookie->printStatus();
        echo 
' *biggrin* ';
    }
}

$cookieMonster = new Client();
$cookieMonster->run();


5/12/2008

Decorator [GoF]

As the first pattern I'd like to introduce the decorator pattern - it's one of the [GoF]- structural patterns. It enables to extend the functionality of a existing method by wrapping a so called decorator-object.

So maybe you already know the situation ;) , your granny is going to bake cookies and you think of how they gonna taste - so cookie is our main-object and the different additional spices and other options which refine the taste of the cookies are the decoration for it. The cookies, pardon main-objects, are fine without the decoration but they're much better with and the best thing is that you're able to combine the decorations... yummy

So that's how this would look like more technically:



Show PHP Source Code

abstract class Cookie {
    protected 
$flavor;
    public function 
__construct($flavor) {
        
$this->flavor=$flavor;
    }    
    abstract public function 
descripeFlavor();
}

class 
GrannysCookie extends Cookie {
    public function 
descripeFlavor() {
        echo 
'<br/>Granny baked a cookie which has a taste of ';
        echo 
$this->flavor;
    }
}

abstract class 
CookieDecorator extends Cookie {
    protected 
$cookie;
    public function 
__construct(Cookie $cookie) {
        
$this->cookie $cookie;
    }    
    
//abstract public function descripeFlavor();    
}

class 
FreshCookieDecorator extends CookieDecorator {
    public function 
descripeFlavor() {
        
$this->cookie->descripeFlavor();
        echo 
' which smells fresh from the oven';
    }
}

class 
CrumbleCookieDecorator extends CookieDecorator {
    public function 
descripeFlavor() {        
        
$this->cookie->descripeFlavor();
        echo 
' it has tasty crumbles ';
    }
}

$cookie = new GrannysCookie('chocolate');
$cookie->descripeFlavor();

$crumbleCookie = new CrumbleCookieDecorator($cookie);
$crumbleCookie->descripeFlavor();

$freshCookie = new FreshCookieDecorator($cookie);
$freshCookie->descripeFlavor();

$freshAndCrumbledCookie = new FreshCookieDecorator($crumbleCookie);
$freshAndCrumbledCookie->descripeFlavor();


additional Information

My Favorites