Showing posts with label design pattern. Show all posts
Showing posts with label design pattern. Show all posts

Monday, June 8, 2009

Design Pattern: Strategy

Strategy is a way to encapsulate, manage and interchange (also at runtime) algorithms.
In the following example, we have three classes (A,B and C) that implement an interface with the method f().
The class AlgoContainer must be initiated by passing the object (external instantiation) or the class name (internal instantation).


Interface StrategyInt
{
public function f();
}

class A implements StrategyInt {
public function f() { print "A:f()"; }
}

class B implements StrategyInt {
public function f() { print "B:f()"; }
}

class C implements StrategyInt {
public function f() { print "C:f()"; }
}

class AlgoContainer {
private $strategy;
private $name;
public function __construct($s){
if (is_object($s))
$this->strategy = $s;
else
$this->strategy = new $s();
}
public function doF() {
$this->strategy->f();
}
}

//Usage 1 (external instantiation):
$ac = new AlgoContainer(new A);
$ac-> doF();

//Usage 2 (internal instantiation):
$ac = new AlgoContainer("A");
$ac-> doF();

Design Pattern: Decorator

Decorator is similar to Proxy.
Basically, decorator is an extension (or wrapper) of the original class (component) and adds features.
A decorator contains a pointer to the component class (initialized by the constructor), and the methods of the component overridden.

Example:


class ImgComponent {
private $src;
private $alt;
public function __construct($name, $src) { /* assign to properties*/ };
public function getHTML() {
return "[ img src="{$this->src}\" alt=\"{$this->alt}\" /]";
}
}

Let's write a decorator:


class ImgWithCaption extends imgComponent
{
private $caption;
private $imgComponent;
public function __construct(&$img, $caption) {
$caption->imgComponent = $caption;
$this->imgComponent = &$img;
};

public function getHTML() {
return "<div><div>{parent::getHTML()}</div>
<div> $caption</div></div>";
}
}

Design Pattern: Adapter

The Adapter design pattern is basically a wrapper, that is a class which provides methods to access to another class.
It's commonly used to normalize incompatibile interfaces.
It's similar to Proxy pattern, but it's a little different. Proxy includes an object and controls accesses to it; Adapter provides an interface to the object, usually by inheritance.



class A {
public static function sort(array $ar) { ... }
}

class B {
private $ar;
public function __construct() {}
public function sortElements() { ... };
public function returnArray() { return $ar;}
}

Now we can extend B and provide the same interface as A



class BAdapter extends B {
public static function sort(array $ar) {
$b = new B($ar);
$b->sortElements();
return $b->returnArray();
}
}

now we can use A and B2 in the same way:



print_r( A::sort(array(3,2,4)) );
print_r( BAdapter ::sort(array(3,2,4)) );

Sunday, June 7, 2009

Design Pattern: Proxy

It provides a filtered controlled access to an object, without exposing it directly.

How to implement in PHP5:
Declare a class:
  • constructor: instantiates the object (only the first time) and keeps the instance into a private properties
  • - implement the methods that provide a controlled access to the internal object
    or
    - use the magic method __call($name, $value), then checks/filters the name and arguments, and may call call_user_func_array($func, $params). The $func parameter ($func) must be an array that contains the object (private property) and the function name ($name passed to __call).
For security obvious reasons, implement also the other magic methods, such as __clone(), __se()t, __get(), __toString()


 

PHP and tips|PHP