Successfully reported this slideshow.
Your SlideShare is downloading. ×

10 PHP Design Patterns #burningkeyboards

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Upcoming SlideShare
Design Patterns in PHP5
Design Patterns in PHP5
Loading in …3
×

Check these out next

1 of 33 Ad

10 PHP Design Patterns #burningkeyboards

Download to read offline

PHP Design patterns

Creational Patterns
Factory
Prototype
Singleton

Structural Patterns
Adapter
Decorator
Facade
Proxy

Behavioral Patterns
Chain of Responsability
Observer
Strategy

PHP Design patterns

Creational Patterns
Factory
Prototype
Singleton

Structural Patterns
Adapter
Decorator
Facade
Proxy

Behavioral Patterns
Chain of Responsability
Observer
Strategy

Advertisement
Advertisement

More Related Content

Slideshows for you (20)

Similar to 10 PHP Design Patterns #burningkeyboards (20)

Advertisement

More from Denis Ristic (20)

Advertisement

10 PHP Design Patterns #burningkeyboards

  1. 1. #BURNINGKEYBOARDS DENIS.RISTIC@PERPETUUM.HR
  2. 2. PHP DESIGN PATTERNS
  3. 3. PHP DESIGN PATTERNS INTRO ▸ Design patterns represent the best practices used by experienced object-oriented software developers. ▸ Design patterns are solutions to general problems that software developers faced during software development. ▸ These solutions were obtained by trial and error by numerous software developers over quite a substantial period of time. 3
  4. 4. PHP DESIGN PATTERNS USAGE OF DESIGN PATTERNS ▸ Common platform for developers ▸ Design patterns provide a standard terminology and are specific to particular scenario. For example, a singleton design pattern signifies use of single object so all developers familiar with single design pattern will make use of single object and they can tell each other that program is following a singleton pattern. ▸ Best Practices ▸ Design patterns have been evolved over a long period of time and they provide best solutions to certain problems faced during software development. Learning these patterns helps un- experienced developers to learn software design in an easy and faster way. 4
  5. 5. PHP DESIGN PATTERNS TYPES OF DESIGN PATTERNS ▸ Creational Patterns ▸ These design patterns provides way to create objects while hiding the creation logic, rather than instantiating objects directly using new operator. This gives program more flexibility in deciding which objects need to be created for a given use case. ▸ Structural Patterns ▸ These design patterns concern class and object composition. Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. ▸ Behavioral Patterns ▸ These design patterns are specifically concerned with communication between objects. 5
  6. 6. PHP DESIGN PATTERNS CREATIONAL PATTERNS ▸ Abstract Factory ▸ Builder ▸ Factory ▸ Prototype ▸ Singleton 6
  7. 7. PHP DESIGN PATTERNS FACTORY ▸ In Factory pattern, we create object without exposing the creation logic to the client and refer to newly created object using a common interface. ▸ Problem: ▸ A framework needs to standardize the architectural model for a range of applications, but allow for individual applications to define their own domain objects and provide for their instantiation. 7
  8. 8. PHP DESIGN PATTERNS FACTORY <?php class Automobile { private $vehicleMake; private $vehicleModel; public function __construct($make, $model) { $this->vehicleMake = $make; $this->vehicleModel = $model; } public function getMakeAndModel() { return $this->vehicleMake . ' ' . $this->vehicleModel; } } class AutomobileFactory { public static function create($make, $model) { return new Automobile($make, $model); } } // have the factory create the Automobile object $Aventador = AutomobileFactory::create('Lomborghini', 'Aventador'); print_r($Aventador->getMakeAndModel()); // outputs "Lomborghinni Aventador" 8
  9. 9. PHP DESIGN PATTERNS PROTOTYPE ▸ This pattern involves implementing a prototype interface which tells to create a clone of the current object. ▸ This pattern is used when creation of object directly is costly. For example, a object is to be created after a costly database operation. ▸ We can cache the object, returns its clone on next request and update the database as as and when needed thus reducing database calls. ▸ Problem ▸ Application "hard wires" the class of object to create in each "new" expression. 9
  10. 10. PHP DESIGN PATTERNS PROTOTYPE <?php class SubObject { static $instances = 0; public $instance; public function __construct() { $this->instance = ++self::$instances; } public function __clone() { $this->instance = ++self::$instances; } } class MyCloneable { public $object1; public $object2; function __clone() { // Force a copy of this->object, otherwise it will point to same object. $this->object1 = clone $this->object1; } } $obj = new MyCloneable(); $obj->object1 = new SubObject(); $obj->object2 = new SubObject(); $obj2 = clone $obj; print("Original Object:n"); print_r($obj); print("Cloned Object:n"); print_r($obj2); 10
  11. 11. PHP DESIGN PATTERNS SINGLETON ▸ This pattern involves a single class which is responsible to create an object while making sure that only single object gets created. ▸ This class provides a way to access its only object which can be accessed directly without need to instantiate the object of the class. ▸ Problem ▸ Application needs one, and only one, instance of an object. Additionally, lazy initialization and global access are necessary. 11
  12. 12. PHP DESIGN PATTERNS SINGLETON <?php class Singleton { private static $instance; /* Returns the *Singleton* instance of this class. */ public static function getInstance() { if (null === static::$instance) { static::$instance = new static(); } return static::$instance; } /* Protected constructor to prevent creating a new instance of the Singleton via the `new` operator from outside of this class. */ protected function __construct() { } /* Private clone method to prevent cloning of the instance of the instance. */ private function __clone() { } /* Private unserialize method to prevent unserializing of the Singleton instance. */ private function __wakeup() { } } class SingletonChild extends Singleton { } $obj = Singleton::getInstance(); var_dump($obj === Singleton::getInstance()); // bool(true) $anotherObj = SingletonChild::getInstance(); var_dump($anotherObj === Singleton::getInstance()); // bool(false) var_dump($anotherObj === SingletonChild::getInstance()); // bool(true) 12
  13. 13. PHP DESIGN PATTERNS STRUCTURAL PATTERNS ▸ Adapter ▸ Bridge ▸ Composite ▸ Decorator ▸ Facade ▸ Flyweight ▸ Null Object ▸ Proxy 13
  14. 14. PHP DESIGN PATTERNS ADAPTER ▸ Adapter pattern works as a bridge between two incompatible interfaces. ▸ This pattern involves a single class which is responsible to join functionalities of independent or incompatible interfaces. ▸ A real life example could be a case of card reader which acts as an adapter between memory card and a laptop. You plugin the memory card into card reader and card reader into the laptop so that memory card can be read via laptop. ▸ Problem ▸ An "off the shelf" component offers compelling functionality that you would like to reuse, but its "view of the world" is not compatible with the philosophy and architecture of the system currently being developed. 14
  15. 15. PHP DESIGN PATTERNS ADAPTER <?php 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; } } class BookAdapter { private $book; function __construct(SimpleBook $book_in) { $this->book = $book_in; } function getAuthorAndTitle() { return $this->book->getTitle().' by '.$this->book->getAuthor(); } } // client print('BEGIN TESTING ADAPTER PATTERN'); $book = new SimpleBook("Gamma, Helm, Johnson, and Vlissides", "Design Patterns"); $bookAdapter = new BookAdapter($book); print('Author and Title: '.$bookAdapter->getAuthorAndTitle()); print('END TESTING ADAPTER PATTERN'); 15
  16. 16. PHP DESIGN PATTERNS DECORATOR ▸ Decorator pattern allows a user to add new functionality to an existing object without altering its structure. ▸ This pattern creates a decorator class which wraps the original class and provides additional functionality keeping class methods signature intact. ▸ Problem ▸ You want to add behavior or state to individual objects at run-time. Inheritance is not feasible because it is static and applies to an entire class. 16
  17. 17. PHP DESIGN PATTERNS DECORATOR <?php class Book { private $author; private $title; function __construct($title_in, $author_in) { $this->author = $author_in; $this->title = $title_in; } function getAuthor() { return $this->author; } function getTitle() { return $this->title; } function getAuthorAndTitle() { return $this->getTitle().' by '.$this->getAuthor(); } } class BookTitleDecorator { protected $book; protected $title; public function __construct(Book $book_in) { $this->book = $book_in; $this->resetTitle(); } //doing this so original object is not altered function resetTitle() { $this->title = $this->book->getTitle(); } function showTitle() { return $this->title; } } 17 class BookTitleExclaimDecorator extends BookTitleDecorator { private $btd; public function __construct(BookTitleDecorator $btd_in) { $this->btd = $btd_in; } function exclaimTitle() { $this->btd->title = "!" . $this->btd->title . "!"; } } class BookTitleStarDecorator extends BookTitleDecorator { private $btd; public function __construct(BookTitleDecorator $btd_in) { $this->btd = $btd_in; } function starTitle() { $this->btd->title = Str_replace(" ","*",$this->btd->title); } } $patternBook = new Book('Gamma', 'Design Patterns'); $decorator = new BookTitleDecorator($patternBook); $starDecorator = new BookTitleStarDecorator($decorator); $exclaimDecorator = new BookTitleExclaimDecorator($decorator); print('showing title : '); print($decorator->showTitle()); print('showing title after two exclaims added : '); $exclaimDecorator->exclaimTitle(); $exclaimDecorator->exclaimTitle(); print($decorator->showTitle()); print('showing title after star added : '); $starDecorator->starTitle(); print($decorator->showTitle()); print('showing title after reset: '); print($decorator->resetTitle()); print($decorator->showTitle());
  18. 18. PHP DESIGN PATTERNS FACADE ▸ Facade pattern hides the complexities of the system and provides an interface to the client using which the client can access the system. ▸ This pattern involves a single class which provides simplified methods required by client and delegates calls to methods of existing system classes. 18
  19. 19. PHP DESIGN PATTERNS FACADE <?php class Book { private $author; private $title; function __construct($title_in, $author_in) { $this->author = $author_in; $this->title = $title_in; } function getAuthor() { return $this->author; } function getTitle() { return $this->title; } function getAuthorAndTitle() { return $this->getTitle() .' by '.$this->getAuthor(); } } class CaseReverseFacade { public static function reverseStringCase($stringIn) { $arrayFromString = ArrayStringFunctions::stringToArray($stringIn); $reversedCaseArray = ArrayCaseReverse::reverseCase($arrayFromString); $reversedCaseString = ArrayStringFunctions::arrayToString($reversedCaseArray); return $reversedCaseString; } } 19 class ArrayCaseReverse { private static $uppercase_array = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', ‘K'); #... private static $lowercase_array = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', ‘k'); #... public static function reverseCase($arrayIn) { $array_out = array(); for ($x = 0; $x < count($arrayIn); $x++) { if (in_array($arrayIn[$x], self::$uppercase_array)) { $key = array_search($arrayIn[$x], self::$uppercase_array); $array_out[$x] = self::$lowercase_array[$key]; } else if (in_array($arrayIn[$x], self::$lowercase_array)) { $key = array_search($arrayIn[$x], self::$lowercase_array); $array_out[$x] = self::$uppercase_array[$key]; } else { $array_out[$x] = $arrayIn[$x]; } } return $array_out; } } class ArrayStringFunctions { public static function arrayToString($arrayIn) { $string_out = null; foreach ($arrayIn as $oneChar) { $string_out .= $oneChar; } return $string_out; } public static function stringToArray($stringIn) { return str_split($stringIn); } } $book = new Book('Design Patterns', 'Gamma, Helm, Johnson, and Vlissides'); print('Original book title: '.$book->getTitle()); $bookTitleReversed = CaseReverseFacade::reverseStringCase($book- >getTitle()); print('Reversed book title: '.$bookTitleReversed);
  20. 20. PHP DESIGN PATTERNS PROXY ▸ In proxy pattern, a class represents functionality of another class. ▸ In proxy pattern, we create object having original object to interface its functionality to outer world. 20
  21. 21. PHP DESIGN PATTERNS PROXY class Book { private $author; private $title; function __construct($title_in, $author_in) { $this->author = $author_in; $this->title = $title_in; } function getAuthor() { return $this->author; } function getTitle() { return $this->title; } } 21 class BookList { private $books = array(); private $bookCount = 0; public function __construct() { } public function getBookCount() { return $this->bookCount; } private function setBookCount($newCount) { $this->bookCount = $newCount; } public function getBook($bookNumberToGet) { if ( (is_numeric($bookNumberToGet)) && ($bookNumberToGet <= $this- >getBookCount())) { return $this->books[$bookNumberToGet]; } return null; } public function addBook(Book $book_in) { $this->setBookCount($this->getBookCount() + 1); $this->books[$this->getBookCount()] = $book_in; return $this->getBookCount(); } public function removeBook(Book $book_in) { $counter = 0; while (++$counter <= $this->getBookCount()) { if ($book_in->getAuthorAndTitle() == $this->books[$counter]- >getAuthorAndTitle()) { for ($x = $counter; $x < $this->getBookCount(); $x++) { $this->books[$x] = $this->books[$x + 1]; } $this->setBookCount($this->getBookCount() - 1); } } return $this->getBookCount(); } }
  22. 22. PHP DESIGN PATTERNS PROXY class ProxyBookList { private $bookList = NULL; //bookList is not instantiated at construct time function __construct() { } function getBookCount() { if (NULL == $this->bookList) { $this->makeBookList(); } return $this->bookList->getBookCount(); } function addBook($book) { if (NULL == $this->bookList) { $this->makeBookList(); } return $this->bookList->addBook($book); } function getBook($bookNum) { if (NULL == $this->bookList) { $this->makeBookList(); } return $this->bookList->getBook($bookNum); } function removeBook($book) { if (NULL == $this->bookList) { $this->makeBookList(); } return $this->bookList->removeBook($book); } function makeBookList() { //Create $this->bookList = new bookList(); } } 22 $proxyBookList = new ProxyBookList(); $inBook = new Book('PHP for Cats','Larry Truett'); $proxyBookList->addBook($inBook); print('test 1 - show the book count after a book is added'); print($proxyBookList->getBookCount()); print('test 2 - show the book'); $outBook = $proxyBookList->getBook(1); print($outBook->getAuthor() . ' by ' . $outBook->getTitle()); $proxyBookList->removeBook($outBook); print('test 3 - show the book count after a book is removed'); print($proxyBookList->getBookCount());
  23. 23. PHP DESIGN PATTERNS BEHAVIORAL PATTERNS ▸ Chain Of Responsibility ▸ Command ▸ Interpreter ▸ Iterator ▸ Mediator ▸ Momento ▸ Observer ▸ State ▸ Strategy ▸ Template Method ▸ Visitor 23
  24. 24. PHP DESIGN PATTERNS CHAIN OF RESPONSIBILITY ▸ As the name suggests, the chain of responsibility pattern creates a chain of receiver objects for a request. ▸ In this pattern, normally each receiver contains reference to another receiver. ▸ If one object cannot handle the request then it passes the same to the next receiver and so on. 24
  25. 25. PHP DESIGN PATTERNS CHAIN OF RESPONSIBILITY <?php abstract class AbstractBookTopic { abstract function getTopic(); abstract function getTitle(); abstract function setTitle($title_in); } class BookTopic extends AbstractBookTopic { private $topic; private $title; function __construct($topic_in) { $this->topic = $topic_in; $this->title = NULL; } function getTopic() { return $this->topic; } //this is the end of the chain - returns title or says there is none function getTitle() { if (NULL != $this->title) { return $this->title; } return 'there is no title avaialble'; } function setTitle($title_in) {$this->title = $title_in;} } 25 class BookSubTopic extends AbstractBookTopic { private $topic; private $parentTopic; private $title; function __construct($topic_in, BookTopic $parentTopic_in) { $this->topic = $topic_in; $this->parentTopic = $parentTopic_in; $this->title = NULL; } function getTopic() { return $this->topic; } function getParentTopic() { return $this->parentTopic; } function getTitle() { if (NULL != $this->title) { return $this->title; } return $this->parentTopic->getTitle(); } function setTitle($title_in) {$this->title = $title_in;} }
  26. 26. PHP DESIGN PATTERNS CHAIN OF RESPONSIBILITY class BookSubSubTopic extends AbstractBookTopic { private $topic; private $parentTopic; private $title; function __construct($topic_in, BookSubTopic $parentTopic_in) { $this->topic = $topic_in; $this->parentTopic = $parentTopic_in; $this->title = NULL; } function getTopic() { return $this->topic; } function getParentTopic() { return $this->parentTopic; } function getTitle() { if (NULL != $this->title) { return $this->title; } return $this->parentTopic->getTitle(); } function setTitle($title_in) {$this->title = $title_in;} } 26 $bookTopic = new BookTopic("PHP 5"); print("bookTopic before title is set:"); print("topic: " . $bookTopic->getTopic() . " title: " . $bookTopic- >getTitle()); $bookTopic->setTitle("PHP 5 Recipes by Babin, Good, Kroman, and Stephens"); print("bookTopic after title is set: "); print("topic: " . $bookTopic->getTopic() . " title: " . $bookTopic- >getTitle()); $bookSubTopic = new BookSubTopic("PHP 5 Patterns",$bookTopic); print("bookSubTopic before title is set: "); print("topic: " . $bookSubTopic->getTopic(). " title: " . $bookSubTopic->getTitle()); $bookSubTopic->setTitle("PHP 5 Objects Patterns and Practice by Zandstra"); print("bookSubTopic after title is set: "); print("topic: ". $bookSubTopic->getTopic() . " title: ". $bookSubTopic->getTitle()); $bookSubSubTopic = new BookSubSubTopic("PHP 5 Patterns for Cats", $bookSubTopic); print("bookSubSubTopic with no title set: "); print("topic: " . $bookSubSubTopic->getTopic() . " title: " . $bookSubSubTopic->getTitle()); $bookSubTopic->setTitle(NULL); print("bookSubSubTopic with no title for set for bookSubTopic either:"); print("topic: " . $bookSubSubTopic->getTopic() . " title: " . $bookSubSubTopic->getTitle());
  27. 27. PHP DESIGN PATTERNS OBSERVER ▸ Observer pattern is used when there is one-to-many relationship between objects such as if one object is modified, its depenedent objects are to be notified automatically. ▸ Observer pattern uses three actor classes: Subject, Observer and Client. ▸ Subject is an object having methods to attach and detach observers to a client object. We have created an abstract class Observer and a concrete class Subject that is extending class Observer. 27
  28. 28. PHP DESIGN PATTERNS OBSERVER <?php abstract class AbstractObserver { abstract function update(AbstractSubject $subject_in); } abstract class AbstractSubject { abstract function attach(AbstractObserver $observer_in); abstract function detach(AbstractObserver $observer_in); abstract function notify(); } 28 class PatternObserver extends AbstractObserver { public function __construct() { } public function update(AbstractSubject $subject) { print('*IN PATTERN OBSERVER - NEW PATTERN GOSSIP ALERT*'); print(' new favorite patterns: '.$subject->getFavorites()); print('*IN PATTERN OBSERVER - PATTERN GOSSIP ALERT OVER*'); } }
  29. 29. PHP DESIGN PATTERNS OBSERVER class PatternSubject extends AbstractSubject { private $favoritePatterns = NULL; private $observers = array(); function __construct() { } function attach(AbstractObserver $observer_in) { //could also use array_push($this->observers, $observer_in); $this->observers[] = $observer_in; } function detach(AbstractObserver $observer_in) { //$key = array_search($observer_in, $this- >observers); foreach($this->observers as $okey => $oval) { if ($oval == $observer_in) { unset($this->observers[$okey]); } } } function notify() { foreach($this->observers as $obs) { $obs->update($this); } } function updateFavorites($newFavorites) { $this->favorites = $newFavorites; $this->notify(); } function getFavorites() { return $this->favorites; } } 29 $patternGossiper = new PatternSubject(); $patternGossipFan = new PatternObserver(); $patternGossiper->attach($patternGossipFan); $patternGossiper->updateFavorites('abstract factory, decorator, visitor'); $patternGossiper->updateFavorites('abstract factory, observer, decorator’); $patternGossiper->detach($patternGossipFan); $patternGossiper->updateFavorites('abstract factory, observer, paisley');
  30. 30. PHP DESIGN PATTERNS STRATEGY ▸ In Strategy pattern, a class behavior or its algorithm can be changed at run time. ▸ In Strategy pattern, we create objects which represent various strategies and a context object whose behavior varies as per its strategy object. ▸ The strategy object changes the executing algorithm of the context object. ▸ We are going to create a Strategy interface defining an action and concrete strategy classes implementing the Strategy interface. ▸ Context is a class which uses a Strategy. 30
  31. 31. PHP DESIGN PATTERNS STRATEGY <?php class Book { private $author; private $title; function __construct($title_in, $author_in) { $this->author = $author_in; $this->title = $title_in; } function getAuthor() { return $this->author; } function getTitle() { return $this->title; } function getAuthorAndTitle() { return $this->getTitle() . ' by ' . $this- >getAuthor(); } } 31 class StrategyContext { private $strategy = NULL; //bookList is not instantiated at construct time public function __construct($strategy_ind_id) { switch ($strategy_ind_id) { case "C": $this->strategy = new StrategyCaps(); break; case "E": $this->strategy = new StrategyExclaim(); break; case "S": $this->strategy = new StrategyStars(); break; } } public function showBookTitle($book) { return $this->strategy->showTitle($book); } } interface StrategyInterface { public function showTitle($book_in); }
  32. 32. PHP DESIGN PATTERNS STRATEGY class StrategyCaps implements StrategyInterface { public function showTitle($book_in) { $title = $book_in->getTitle(); $this->titleCount++; return strtoupper ($title); } } class StrategyExclaim implements StrategyInterface { public function showTitle($book_in) { $title = $book_in->getTitle(); $this->titleCount++; return Str_replace(' ','!',$title); } } class StrategyStars implements StrategyInterface { public function showTitle($book_in) { $title = $book_in->getTitle(); $this->titleCount++; return Str_replace(' ','*',$title); } } 32 $book = new Book('PHP for Cats','Larry Truett'); $strategyContextC = new StrategyContext('C'); $strategyContextE = new StrategyContext('E'); $strategyContextS = new StrategyContext('S'); print('test 1 - show name context C'); print($strategyContextC->showBookTitle($book)); print('test 2 - show name context E'); print($strategyContextE->showBookTitle($book)); print('test 3 - show name context S'); print($strategyContextS->showBookTitle($book));
  33. 33. PHP DESIGN PATTERNS PHP DESIGN PATTERNS REFERENCES ▸ Design Patterns in PHP ▸ https://github.com/ehsangazar/design-patterns-php ▸ Design Patterns - PHP The Right Way ▸ http://www.phptherightway.com/pages/Design- Patterns.html ▸ Design Patterns in Java ▸ https://www.tutorialspoint.com/design_pattern/ index.htm 33

×