Design Patterns and Usage

Post on 27-Nov-2014

158 Views

Category:

Software

4 Downloads

Preview:

Click to see full reader

DESCRIPTION

We often come across the term "Design Patterns" but some of us might be interested to know what they truly are. Its necessary to know the value and benefits design patterns bring to the software development process, mostly in the areas of maintenance and code reuse.

Transcript

Design PatternsUsage and Application

By Manas Ranjan Sahoo

1. 23 common problems best accepted solutions

1. Started at IBM 1994

1. Solutions can be successfully applied to right problems

1. Using DP the risk of solutions becomes zero

1. These are well thought and tested solutions

1. Solution templates for re-occurring programming challenges

What is it?

1. A design pattern is a solution to common problems that have already been discovered, documented, and is in wide use

1. Don't think of patterns as data structures, or algorithms

1. Think as if your code as people sending messages, like sending letters, to each other

1. Each object is a 'person'.

1. The way that you'd organize the 'people' and the patterns they use to send messages to each other are the patterns

1. Patterns deals with relationships and interactions of classes and objects

● A good working knowledge of the patterns saves inventing your own solutions to well-known problems.

● It is analogous to abstract data types: every coder should know what a stack, list and queue are and recognize when it is appropriate to use them - they should not write code first and then say "Oh I could have just used a Stack there."

● You can alter a given class without changing the rest of the code that interacts with it.

Why

● The key is to learn to identify the scenarios and problems which the patterns are meant to address. Then applying the pattern is simply a matter of using the right tool for the job.

● Patterns save time because we don’t have to solve a problem that’s already been solved.

● Design patterns have two major benefits. - They provide help us identifying a proven solution which facilitates the development of highly cohesive modules with minimal coupling.

- They make communication between designers more efficient.

● Factory ● Singleton● Delegate● Decorator● Strategy● Observer● Adapter● State● Iterator● Front Controller● MVC● Active Record

Types

● Most Commonly used

● A class simply creates the object you want to use

● We can define a factory as a simple design pattern that give us a convenient way to instantiate objects.

● we create object without exposing the creation logic to the client and refer to newly created object using a common interface.

Factory Pattern

class Thing {public function do_something() {

echo 'Hello PHPeople';}

}

class Factory {public function create_thing() {

return new Thing();}

}

$factory = new Factory();$thing = $factory->create_thing();$thing->do_something();

● When designing web applications, we often need to allow access to one and only one instance of a particular class.

● These ensure there is a single class instance and that is global point of access for it.

Singleton Pattern

You use a singleton when you need to manage a shared resource. For instance a printer spooler.

Your application should only have a single instance of the spooler in order to avoid conflicting request for the same resource.

Useful when only one object is required across the system.

When to Use

class DatabaseConnection { private static $singleton_instance = null; private function construct__() { // private ensures // that this object is not created as a new intance // outside of this class. } public static function global_instance() { static $singleton_instance = null; if($singleton_instance === null) { $singleton_instance = new DatabaseConnection(); } return($singleton_instance); } public function exec_query($query) { print "Running query: " . $query; } }

// We create a database instance by running the static function// which returns the singleton instance of the class

$db_connection = DatabaseConnection::global_instance();

In this an object, instead of performing one of its stated tasks, delegates that task to an associated helper object

The helper object is known as a delegate.

Delegate is given the responsibility to execute a task for the delegator.

Delegator Pattern

interface Printer { public function printline($subject);}

class DelegatePrinter implements Printer { public function printline($subject) { print $subject; } }

class Client { public function __construct() { $this->printer = new DelegatePrinter; } public function printData() { $this->printer->printline('Some string data'); }}

$client = new Client;$client->printData();

Its a pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class

Decorator uses Delegation, it is a subset of delegation.

Decorator works best when you want to take something that's working and have it do something else, but not change the interface at all

Decorator is used to construct a complex object by using mechanism called Delegation

Decorator Pattern

class Book { private $title;public function __construct($title_in) {

$this->title = $title_in;}public function getTitle() {

return $this->title; } //we need to implement showtitle method here }

class BookTitleDecorator { private $book;

private $title; public function __construct(Book $bookobj) {

$this->book = $bookobj; $this->title = $this->book->getTitle(); }

public function showTitle() { return $this->title; }}

include_once('Book.php');

include_once('BookTitleDecorator.php');

$DesignPatternBook = new Book("Design Patterns Book explaining Decorators");

$decorator = new BookTitleDecorator($DesignPatternBook);

echo $decorator->showTitle();

Here a context will choose the appropriate concrete extension of a class interface.

Capture the abstraction in an interface, bury implementation details in derived classes.

Strategy lets you change the guts of an object. Decorator lets you change the skin.

Example - Mode of travel to reach Airport

Strategy Pattern

class StrategyContext { ///context for chosing extension private $strategy = NULL;

public function __construct($strategy_id) { switch ($strategy_id) { case "A": $this->strategy = new StrategyA(); break; }

}

public function showBookTitle($book) { return $this->strategy->showTitle($book);

} }

interface StrategyInterface { //abstraction capturedpublic function showTitle($bookobj);

}

class StrategyA implements StrategyInterface { //implementaion detail here public function showTitle($bookobj) { $title = $bookobj->getTitle(); return strtoupper ($title); } }

class Book {private $title; function __construct($title) { $this->title = $title; } function getTitle() {return $this->title;}

}

$book = new Book('PHP for Cats'); $strategyContextA = new StrategyContext('A'); echo $strategyContextA->showBookTitle($book);

This is a design pattern in which an object, register multiple dependents, called observers, and notifies them automatically of any state changes

Observers look for changes and do something

Example - A newspaper and subscribers

Its used when a state change in subject affects other objects, and you don't know how many objects need to be changed

Observer Pattern

abstract class Publisher {abstract function attach(Observer $observer);abstract function detach(Observer $observer);abstract function notify();

}abstract class Observer {

abstract function update(Publisher $subject_in);}class Account extends Publisher{ public $status = NULL; public $_observers = array(); function attach(Observer $observer_in) { array_push($this->_observers, $observer_in); } function detach(Observer $observer_in) { $this->_observers = array_diff($this->_observers, array($observer_in)); } public function notify() { foreach($this->_observers as $obs) { $obs->update($this); } }}

class Logger extends Observer{ public function __construct() { } public function update(Publisher $pub) { //Update status in log table echo "Updating status in log table.\n"; }}

include_once('Account.php');include_once('Logger.php'); $account = new Account();$logger = new Logger();$account->attach($logger);$account->status = "Expired";$account->notify();

This pattern is used when we want to convert the interface one class to an interface which can be used by another class.

whenever there is a problem that requires the continued stability of the main platform and does not disrupt the existing application flow, the Adapter Design Pattern could be used in developing the solution.

Real-world examples might be a language translator, or a mobile charger.

It involves a single class called adapter which is responsible for communication between 2 incompatible classes.

Adapter Pattern

class Book {

private $title;private $price;

function __construct($title, $price) { $this->title = $title; $this->price = $price;

}

function getTitle() { return $this->title;

}

function getPrice() { return $this->price;

}

}

class BookAdapter {

private $book;function __construct(Book $bookobj) {

$this->book = $bookobj;}function getTitleAndPrice() {

return $this->book->getTitle().' - '.$this->book->getPrice();}

}

$book = new Book("Design Patterns", "$125"); $bookAdapter = new BookAdapter($book); print('Title and Price: '.$bookAdapter->getTitleAndPrice());

All our final decisions are made in a state of mind that is not going to last — Marcel Proust

The purpose is to allow an object to change its behavior when the state

changes.

It is used to allow an object to changes it’s behaviour when it’s internal state changes

A class will change it's behavior when circumstances change.

State Pattern

interface State {function press(StopWatchContext $context);

}class StopState implements State {

public function press(StopWatchContext $context) { $time = (microtime(TRUE) * 1000) - $context->getStartTime(); printf("The stop watch is stopped. [Time] %d MS <br>", $time);; $context->setState($context->getStartState()); // State is changed here

}}class StartState implements State {

public function press(StopWatchContext $context) { echo "The stop watch is running..<br>"; $context->setState($context->getStopState()); // State is changed here

}}class ResetState implements State {

public function press(StopWatchContext $context) { echo "The stop watch is reset. <br>"; $context->setStartTime(microtime(TRUE) * 1000); $context->setState($context->getStartState()); // State is changed here

}}

class StopWatchContext {private $state;private $startTime;private $startState;private $stopState;private $resetState;

public function __construct() { $this->setStartTime();

$this->startState = new StartState(); $this->stopState = new StopState(); $this->resetState = new ResetState(); $this->state = $this->startState;

}

public function setState(State $state) { $this->state = $state;

}

public function pressButton() { $this->state->press($this);

}

public function resetButton() { $this->setState(new ResetState()); $this->pressButton();

}public function getStartTime() {

return $this->startTime;}public function setStartTime() {

$this->startTime = microtime(TRUE) * 1000;}public function getStartState() {

return $this->startState;}public function getStopState() {

return $this->stopState;}public function getResetState() {

return $this->resetState;}

}

$timer = new StopWatchContext();$timer->pressButton(); //startedusleep(1200 * 1000); // sleeping 1.2 seconds$timer->pressButton(); //stopped

$timer->pressButton(); //startedusleep(2000 * 1000); //sleeping 1.7 seconds (3200 MS)$timer->pressButton();//stopped

$timer->resetButton(); //reset$timer->pressButton();//startedsleep(2);//sleeping 2 seconds$timer->pressButton(); //stopped

Not all objects are the same when it comes to looping.

It helps construct objects that can provide a single standard interface to loop or iterate through any type of countable data.

When dealing with countable data that needs to be traversed, creating an object based on the Iterator Design Pattern is the best solution.

Iterator Pattern

class AddressDisplay{ private $addressType; private $addressText;

public function setAddressType($addressType) { $this->addressType = $addressType; }

public function getAddressType() { return $this->addressType; }

public function setAddressText($addressText) { $this->addressText = $addressText; }

public function getAddressText() { return $this->addressText; }}

class EmailAddress{ private $emailAddress; public function getEmailAddress() { return $this->emailAddress; } public function setEmailAddress($address) { $this->emailAddress = $address; }}

class PhysicalAddress{ private $streetAddress; private $city; private $state; private $postalCode;

public function __construct($streetAddress, $city, $state, $postalCode) { $this->streetAddress = $streetAddress; $this->city = $city; $this->state = $state; $this->postalCode = $postalCode; } public function getStreetAddress() { return $this->streetAddress; } public function getCity() { return $this->city; } public function getState() { return $this->state; } public function getPostalCode() { return $this->postalCode; } public function setStreetAddress($streetAddress) { $this->streetAddress = $streetAddress; } public function setCity($city) { $this->city = $city; }

public function setState($state) { $this->state = $state; } public function setPostalCode($postalCode) { $this->postalCode = $postalCode; }}

class PersonAddressIterator implements AddressIterator{

private $emailAddresses;private $physicalAddresses;private $position;

public function __construct($emailAddresses){

$this->emailAddresses = $emailAddresses; $this->position = 0;

}

public function hasNext(){

if ($this->position >= count($this->emailAddresses) || $this->emailAddresses[$this->position] == null) { return false; } else { return true; }

}

public function next(){

$item = $this->emailAddresses[$this->position]; $this->position = $this->position + 1; return $item;

} }

It relates to the design of web applications.

It "provides a centralized entry point for handling requests

All request send to the application are processed with it, which then redirects each request to the corresponding Action Controller

Example: The login.php on specific request instantiate further objects and call methods to handle the particular task(s) required.

Yii, CakePHP, Laravel, Symfony, CodeIgniter and Zend Framework, Magento, MVC frameworks uses front controller

Front Controller Pattern

Its a for implementing user interfaces.

It divides a given software application into three interconnected parts, so as to separate internal representations of information from users.

The model directly manages the data, logic and rules of the application.

A view can be any output representation of information.

The controller, accepts input and converts it to commands for the model or view.

MVC Pattern

This is pattern found in software that stores its data in relational databases.

The interface of the object using this pattern would include functions such as Insert, Update, and Delete operations

We can say this as an approach to accessing data in a database.

Laravel contains an ORM called 'Eloquent' which implements the active record pattern.

CakePHP's ORM implements the active record pattern.

A database table is wrapped into a class.

An object instance is tied to a single row in the table.

Active Record Pattern

MVC

Magento leverages xml to drive the configuration and actions of the application on top of the regular Model-View-Controller architecture.

Front Controller

Magneto has a single entry point (index.php) for all of it's requests.

Factory

The Factory Method is used to instantiate classes in Magento.

Singleton

In magento Singleton pattern is instantiated for Blocks and Classes.

Magento Patterns

Registry

Its basically a pattern that allows any object or data to be available in a public global scope for any resource to use.

Object Pool

The Object Pool Pattern keeps objects ready for use over and over again instead of re-instantiating them and destroying them once finished.

Iterator

Magento allows an object traverse through the elements of another class.

The core/resource_iterator model allows you to get the collection item data one by one executing corresponding SQL query.

Module

Magneto is based on modular programming and emphasizes the grouping of functionality of a program into independent, interchangeable modules.

Observer

Magento uses observer pattern by providing event listeners through which other components of the application can "hook" into this event listener and execute their code.

References

http://www.wrox.com/WileyCDA/WroxTitle/Professional-PHP-Design-Patterns.productCd-0470496703.html

http://www.phptherightway.com/pages/Design-Patterns.html

http://www.fluffycat.com/PHP-Design-Patterns/

http://en.wikipedia.org/wiki/Design_Patterns

http://www.oodesign.com

http://sourcemaking.com/design_patterns

THANK YOU!

top related