Software Design Patterns (2)

apatheticyogurtΛογισμικό & κατασκευή λογ/κού

13 Δεκ 2013 (πριν από 3 χρόνια και 5 μήνες)

69 εμφανίσεις

Software Design Patterns (2)

four commonly used design

patterns using php

(singleton, factory, adapter & decorator)

the singleton pattern (1)

o

when only one object needs to be responsible for a
particular task.

o

exclusive resource with only one type of this resource.

o

most commonly used in PHP to limit connections to the
database throughout the codebase.

o

singleton pattern considered a responsibility pattern
because it delegates control for creation to a single point.

o

All singleton patterns have at least three common
elements:

-

they must have a constructor, and it must be marked private

-

they contain a static member variable that will hold an instance
of the class

-

they contain a public static method to access the instance

basic form:


class Singleton {


private static $instance = null;


private static function __construct() { }




public static function getInstance() {



if(empty(self::$instance) {




self::$instance = new Singleton();



}



return self::$instance;


}

}

the singleton pattern (2)

the singleton pattern (3)

class Database {


private $_db;


static $_instance;



private function __construct() {


$this
-
>_db = mysql_connect('localhost', 'root', '');


mysql_select_db('phobias');


}



private function __clone() {}



public static function getInstance() {


if(!(self::$_instance instanceof self)) {


self::$_instance = new self();


}


return self::$_instance;


}



public function query($sql) {


return mysql_query($sql, $this
-
>_db);


}

}

$db = Database::getInstance();


$result = $db
-
>query("SELECT * FROM phobias



WHERE def LIKE '%pain%'");


while ($row = mysql_fetch_assoc($result)) {


echo $row["term"].' :
'

.




$row["def"].'<br/>';

}

test singleton:

run test

view code

the singleton pattern (4)

the factory pattern (1)

o

the factory pattern is a class that creates objects.


o

a factory is typically used to return different classes that
conform to a similar interface.


o

usually, a factory pattern has one key ingredient: a static
method, which is by convention named “factory”.


o

the static method may take any number of arguments and
must return an object.


o

factories are critically important to the practice of
polymorphic programming.

the factory pattern (2)

basic form:



class Driver {


# The parameterized factory method


public static function factory($type) {


if (include_once 'Drivers/' . $type . '.php') {


$classname = 'Driver_' . $type;


return new $classname;


} else {


throw new Exception('Driver not found');


}


}

}

# Load a MySQL Driver

$mysql = Driver::factory('MySQL');


# Load an SQLite Driver

$sqlite = Driver::factory('SQLite');

the factory pattern (3)

interface DB {


public function connect();


public function query();


public function disconnect();

}


class DBmysql implements DB {


public function connect() { //database connection stuff }


public function query() { //perform database query stuff }


public function disconnect() { //disconnect database }

}


class DBoracle implements DB {


public function connect() { //database connection stuff }


public function query() { //perform database query stuff }


public function disconnect() { //disconnect database }

}

the factory pattern (4)

class DBfactory {


public static $_DB;



public static function &factory($szType = "") {


if(!is_object(self::$_DB)) {


switch($szType) {


case 'mysql':


self::$_DB = new DBmysql;


break;


case ‘oracle':


self::$_DB = new DBoracle;


break;


default:


self::$_DB = new DBmysql;


break;


}


}


return self::$_DB;


}

}


the factory pattern (5)

db = DBfactory::factory("mysql");

$db
-
>query("..");


DBfactory::factory()
-
>query("..");

factory can now create different driver objects (default mysql):

aside : Type Hinting

http://www.youtube.com/watch?v=oGeecEUK6cw&feature=related

the factory pattern (6)

the adapter pattern (1)

o

the adapter pattern simply converts the interface of
one class to what another class expects.


o

for this reason, it is often referred to as a "wrapper"
pattern.


o

adapters are helpful when a class doesn't have quite
the exact methods needed, and its not possible to
change the original class.


o

the adapter can take the methods accessible in the
original class, and adapt them into the methods needed.

the adapter pattern (2)

class SimpleBook {




private $author;



private $title;



function __construct($author_in, $title_in) {




$this
-
>author = $author_in;




$this
-
>title = $title_in;



}



function getAuthor() {



return $this
-
>author;


}



function getTitle() {



return $this
-
>title;


}

}

the adapter pattern (3)

class BookAdapter {



private $book;



function __construct(SimpleBook $book_in) {




$this
-
>book = $book_in;




}




function getAuthorAndTitle() {




return $this
-
>book
-
>getTitle() . ' by ' .
$this
-
>book
-
>getAuthor();



}

}


$book = new SimpleBook("Gamma, Helm, Johnson, and
Vlissides", "Design Patterns");



$bookAdapter = new BookAdapter($book);

echo 'Author and Title: '.$bookAdapter
-
>getAuthorAndTitle();

run test

view code

the decorator pattern (1)

o

the point of the decorator pattern is to enhance an object
with some functionality without modifying the structure of the
original object.


o

the decorator pattern is often used an example of the
principle of preferring "composition over inheritance"
http://en.wikipedia.org/wiki/Composition_over_inheritance

class Cupcake {


public $Toppings = array('sprinkles' => 0,
'frosting' => 'none');




public function __construct($int, $str) {



$this
-
>Toppings['sprinkles'] = $int;



$this
-
>Toppings['frosting'] = $str;


}

}


abstract class Decorator_Wrapper {


abstract function Add($mixed);


abstract function Remove($mixed);

}

the decorator pattern (2)

class Sprinkle_Decorator extends Decorator_Wrapper {


public function __construct(Cupcake $c) {



$this
-
>Cupcake = $c;


}




public function Add($int) {



$this
-
>Cupcake
-
>Toppings['sprinkles'] += $int;


}




public function Remove($int) {



$this
-
>Cupcake
-
>Toppings['sprinkles']
-
= $int;


}

}


the decorator pattern (3)

the decorator pattern (4)

class Frosting_Decorator extends Decorator_Wrapper {


public function __construct(Cupcake $c) {



$this
-
>Cupcake = $c;


}




public function Add($str) {



$this
-
>Cupcake
-
>Toppings['frosting'] = $str;


}




public function Remove($str) {



echo "Hrmm.. We cant seem to remove your $str,
it's stuck on the muffin!";


}

}

# Test the decorator pattern

echo '<p>Make a new cupcake!</p>';

$cupcake = new Cupcake(5, 'none');

print_r($cupcake
-
>Toppings);


echo '<p>Add more sprinkles!</p>' ;

$sprinkle = new Sprinkle_Decorator($cupcake);

$sprinkle
-
>Add('55');

print_r($cupcake
-
>Toppings);


echo '<p>Remove 25 sprinkles!</p>' ;

$sprinkle
-
>Remove('25');

print_r($cupcake
-
>Toppings);


echo '<p>Add some frosting :)</p>';

$frosting = new Frosting_Decorator($cupcake);

$frosting
-
>Add('Chocolate');print_r($cupcake
-
>Toppings);

the decorator pattern (5)

run test

view code