This article is for translating articles Original address: Design Patterns in PHP If you intend to learn PHP children's shoes can refer to the author's programming language learning Knowledge system Essentials List This article mainly discusses in the web development, is accurate, is the PHP development the related design pattern and the application. Experienced developers are sure to be familiar with design patterns, but this article is intended primarily for novice developers. First we need to figure out what the design pattern is, design patterns are not a pattern to interpret, they are not a common data structure like linked lists, or a particular application or framework design. In fact, the design pattern is explained as follows: Descriptions of communicating objects and classes that is customized to solve a general design problem in a particular CO ntext. On the other hand, design patterns provide a broad and reusable way to solve the problems we often encounter in our daily programming. Design patterns are not necessarily a class library or a third-party framework, they are more of a thought and widely used in the system. They also represent a pattern or template that can be used to solve problems in several different scenarios. Design patterns can be used to speed up development, and many large ideas or designs are implemented in a simple way. Of course, while design patterns work well in development, it's important to avoid misusing them in inappropriate scenarios. At present, there are 23 kinds of design patterns, which can be divided into the following three categories according to the use target: Create pattern: Used to create an object to decouple an object from the implementation. Schema mode: Used to construct large object structures between different objects. Behavior patterns: Used to manage algorithms, relationships, and responsibilities between different objects. Creational Patternssingleton (singleton mode)Singleton mode is one of the most common patterns that are often used in Web application development to allow an accessible instance to be created at run time for a particular class.
- /**
- * Singleton Class
- */
- Final class Product
- {
- /**
- * @var Self
- */
- private static $instance;
- /**
- * @var Mixed
- */
- Public $mix;
- /**
- * Return Self instance
- *
- * @return Self
- */
- public static function getinstance () {
- if (! ( Self:: $instance instanceof Self)) {
- Self:: $instance = new self ();
- }
- Return self:: $instance;
- }
- Private Function __construct () {
- }
- Private Function __clone () {
- }
- }
- $firstProduct = Product::getinstance ();
- $secondProduct = Product::getinstance ();
- $firstProduct->mix = ' Test ';
- $secondProduct->mix = ' example ';
- Print_r ($firstProduct->mix);
- Example
- Print_r ($secondProduct->mix);
- Example
Copy CodeIn many cases, it is necessary to create a singleton construct for multiple classes in the system, so that a common abstract parent factory method can be established:
-
- Abstract class Factoryabstract {
- protected static $instances = Array ();
- public static function getinstance () {
- $className = Static::getclassname ();
- if (! ( Self:: $instances [$className] instanceof $className)) {
- Self:: $instances [$className] = new $className ();
- }
- Return self:: $instances [$className];
- }
- public static function RemoveInstance () {
- $className = Static::getclassname ();
- if (Array_key_exists ($className, Self:: $instances)) {
- Unset (self:: $instances [$className]);
- }
- }
- Final protected static function GetClassName () {
- return Get_called_class ();
- }
- protected function __construct () {}
- Final protected function __clone () {}
- }
- Abstract class Factory extends Factoryabstract {
- Final public static function getinstance () {
- return Parent::getinstance ();
- }
- Final public static function RemoveInstance () {
- Parent::removeinstance ();
- }
- }
- Using
- Class Firstproduct extends Factory {
- Public $a = [];
- }
- Class Secondproduct extends Firstproduct {
- }
- Firstproduct::getinstance ()->a[] = 1;
- Secondproduct::getinstance ()->a[] = 2;
- Firstproduct::getinstance ()->a[] = 3;
- Secondproduct::getinstance ()->a[] = 4;
- Print_r (Firstproduct::getinstance ()->a);
- Array (1, 3)
- Print_r (Secondproduct::getinstance ()->a);
- Array (2, 4)
Copy CodeRegistryThe registry mode is not very common, it is not a typical creation mode, just to make use of static methods more convenient access to data.
- /**
- * Registry Class
- */
- Class Package {
- protected static $data = Array ();
- public static function set ($key, $value) {
- Self:: $data [$key] = $value;
- }
- public static function Get ($key) {
- Return Isset (self:: $data [$key])? Self:: $data [$key]: null;
- }
- Final public static function Removeobject ($key) {
- if (Array_key_exists ($key, Self:: $data)) {
- Unset (self:: $data [$key]);
- }
- }
- }
- Package::set (' name ', ' package name ');
- Print_r (Package::get (' name '));
- Package Name
Copy CodeFactory (Factory mode)The factory pattern is another very common pattern, as its name implies: it is indeed the production factory of the object instance. In some sense, the factory model provides a common approach that helps us get to the object without having to care about its specific intrinsic implementation.
-
- Interface Factory {
- Public function getproduct ();
- }
- Interface Product {
- Public function getName ();
- }
- Class Firstfactory implements Factory {
- Public Function getproduct () {
- return new Firstproduct ();
- }
- }
- Class Secondfactory implements Factory {
- Public Function getproduct () {
- return new Secondproduct ();
- }
- }
- Class Firstproduct implements Product {
- Public Function GetName () {
- Return ' the first product ';
- }
- }
- Class Secondproduct implements Product {
- Public Function GetName () {
- Return ' Second product ';
- }
- }
- $factory = new Firstfactory ();
- $firstProduct = $factory->getproduct ();
- $factory = new Secondfactory ();
- $secondProduct = $factory->getproduct ();
- Print_r ($firstProduct->getname ());
- The first product
- Print_r ($secondProduct->getname ());
- Second Product
Copy CodeAbstractfactory (abstract Factory mode)In some cases we need to provide different construction plants based on different selection logic, whereas for multiple plants a unified abstraction plant is required:
-
- Class Config {
- public static $factory = 1;
- }
- Interface Product {
- Public function getName ();
- }
- Abstract class Abstractfactory {
- public static function GetFactory () {
- Switch (Config:: $factory) {
- Case 1:
- return new Firstfactory ();
- Case 2:
- return new Secondfactory ();
- }
- throw new Exception (' bad config ');
- }
- Abstract public Function getproduct ();
- }
- Class Firstfactory extends Abstractfactory {
- Public Function getproduct () {
- return new Firstproduct ();
- }
- }
- Class Firstproduct implements Product {
- Public Function GetName () {
- Return ' the product from the first factory ';
- }
- }
- Class Secondfactory extends Abstractfactory {
- Public Function getproduct () {
- return new Secondproduct ();
- }
- }
- Class Secondproduct implements Product {
- Public Function GetName () {
- Return ' the product from second factory ';
- }
- }
- $firstProduct = Abstractfactory::getfactory ()->getproduct ();
- Config:: $factory = 2;
- $secondProduct = Abstractfactory::getfactory ()->getproduct ();
- Print_r ($firstProduct->getname ());
- The first product from the first factory
- Print_r ($secondProduct->getname ());
- Second Product from Second factory
Copy CodeObject PoolAn object pool can be used to construct and hold a series of objects and get calls when needed:
-
- Class Product {
- protected $id;
- Public function __construct ($id) {
- $this->id = $id;
- }
- Public Function getId () {
- return $this->id;
- }
- }
- Class Factory {
- protected static $products = Array ();
- public static function Pushproduct (Product $product) {
- Self:: $products [$product->getid ()] = $product;
- }
- public static function GetProduct ($id) {
- Return Isset (self:: $products [$id])? Self:: $products [$id]: null;
- }
- public static function Removeproduct ($id) {
- if (Array_key_exists ($id, Self:: $products)) {
- Unset (self:: $products [$id]);
- }
- }
- }
- Factory::p ushproduct (New Product (' first '));
- Factory::p ushproduct (New Product (' second '));
- Print_r (Factory::getproduct (' first ')->getid ());
- First
- Print_r (Factory::getproduct (' second ')->getid ());
- Second
Copy CodeLazy initialization (deferred initialization)Lazy initialization of a variable is often used, and for a class it is often not known which function is used, and some functions are often used only once.
-
- Interface Product {
- Public function getName ();
- }
- Class Factory {
- protected $firstProduct;
- protected $secondProduct;
- Public Function getfirstproduct () {
- if (! $this->firstproduct) {
- $this->firstproduct = new Firstproduct ();
- }
- return $this->firstproduct;
- }
- Public Function getsecondproduct () {
- if (! $this->secondproduct) {
- $this->secondproduct = new Secondproduct ();
- }
- return $this->secondproduct;
- }
- }
- Class Firstproduct implements Product {
- Public Function GetName () {
- Return ' the first product ';
- }
- }
- Class Secondproduct implements Product {
- Public Function GetName () {
- Return ' Second product ';
- }
- }
- $factory = new Factory ();
- Print_r ($factory->getfirstproduct ()->getname ());
- The first product
- Print_r ($factory->getsecondproduct ()->getname ());
- Second Product
- Print_r ($factory->getfirstproduct ()->getname ());
- The first product
Copy CodePrototype (prototype mode)Sometimes, some objects need to be initialized multiple times. And especially if initialization takes a lot of time and resources to pre-initialize and store those objects.
- !--? php
- interface Product {
- }
-
- class Factory {
-
- private $product;
-
- Public Function __construct (Product $product) {
- $this->product = $product;
- }
-
- public Function getproduct () {
- return clone $this->product;
- }
- }
-
- class Someproduct implements Product {
- public $name;
- }
-
-
- $prototypeFactory = new Factory (new Someproduct ());
-
- $firstProduct = $prototypeFactory->getproduct ();
- $firstProduct->name = ' the first product ';
-
- $secondProduct = $prototypeFactory->getproduct ();
- $secondProduct->name = ' Second product ';
-
- print_r ($firstProduct->name);
- //The first product
- Print_r ($secondProduct->name);
- //Second product
Copy CodeBuilder (constructor)The constructor pattern is primarily about creating complex objects:
-
- Class Product {
- Private $name;
- Public Function SetName ($name) {
- $this->name = $name;
- }
- Public Function GetName () {
- return $this->name;
- }
- }
- Abstract class Builder {
- protected $product;
- Final public Function getproduct () {
- return $this->product;
- }
- Public Function buildproduct () {
- $this->product = new product ();
- }
- }
- Class Firstbuilder extends Builder {
- Public Function buildproduct () {
- Parent::buildproduct ();
- $this->product->setname (' The product of the first builder ');
- }
- }
- Class Secondbuilder extends Builder {
- Public Function buildproduct () {
- Parent::buildproduct ();
- $this->product->setname (' The product of Second Builder ');
- }
- }
- Class Factory {
- Private $builder;
- Public function __construct (Builder $builder) {
- $this->builder = $builder;
- $this->builder->buildproduct ();
- }
- Public Function getproduct () {
- return $this->builder->getproduct ();
- }
- }
- $firstDirector = new Factory (new Firstbuilder ());
- $secondDirector = new Factory (new Secondbuilder ());
- Print_r ($firstDirector->getproduct ()->getname ());
- The product of the first builder
- Print_r ($secondDirector->getproduct ()->getname ());
- The product of second builder
Copy CodeStructural Patternsdecorator (Adorner mode)Adorner mode allows us to dynamically add different behavioral actions to an object's invocation, depending on the runtime's different scenarios.
- Class Htmltemplate {
- Any parent class methods
- }
- Class Template1 extends Htmltemplate {
- protected $_html;
- Public Function __construct () {
- $this->_html = "
__text__ ";
- }
- Public function set ($html) {
- $this->_html = $html;
- }
- Public function render () {
- Echo $this->_html;
- }
- }
- Class Template2 extends Htmltemplate {
- protected $_element;
- Public function __construct ($s) {
- $this->_element = $s;
- $this->set ("
" . $this->_html. " ");
- }
- Public Function __call ($name, $args) {
- $this->_element-> $name ($args [0]);
- }
- }
- Class Template3 extends Htmltemplate {
- protected $_element;
- Public function __construct ($s) {
- $this->_element = $s;
- $this->set ("". $this->_html. "");
- }
- Public Function __call ($name, $args) {
- $this->_element-> $name ($args [0]);
- }
- }
Copy CodeAdapter (Adapter mode)This mode allows the use of different interfaces to refactor a class, allowing calls to be made using different invocation methods:
-
- 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 ();
- }
- }
- Usage
- $book = new Simplebook ("Gamma, Helm, Johnson, and Vlissides", "Design Patterns");
- $bookAdapter = new Bookadapter ($book);
- Echo ' Author and Title: '. $bookAdapter->getauthorandtitle ();
- function echo $line _in) {
- echo $line _in. "
";
- }
Copy CodeBehavioral Patternsstrategy (Policy mode)The test pattern is primarily intended to allow the customer class to better use certain algorithms without needing to know their specific implementations.
-
- Interface Outputinterface {
- Public function load ();
- }
- Class Serializedarrayoutput implements Outputinterface {
- Public function load () {
- Return serialize ($arrayOfData);
- }
- }
- Class Jsonstringoutput implements Outputinterface {
- Public function load () {
- Return Json_encode ($arrayOfData);
- }
- }
- Class Arrayoutput implements Outputinterface {
- Public function load () {
- return $arrayOfData;
- }
- }
Copy CodeObserver (Viewer mode)An object can be set to be observable, as long as it allows other objects to be registered as observers in some way. Whenever the object being observed changes, a message is sent to the observer.
- !--? php
- interface Observer {
- function onChanged ($sender, $args);
- }
-
- interface Observable {
- function addobserver ($observer);
- }
-
- class CustomerList implements Observable {
- private $_observers = Array ();
-
- Public Function Addcustomer ($name) {
- foreach ($this->_observers as $obs)
- $obs OnChanged ($this, $name);
- }
-
- public Function Addobserver ($observer) {
- $this->_observers []= $observer;
- }
- }
-
- class Customerlistlogger implements Observer {
- public function Onchan Ged ($sender, $args) {
- echo ("' $args ' Customer have been added to the list \ n");
- }
- }
-
- $ul = new UserList ();
- $ul->addobserver (New Customerlistlogger ());
- $ul->addcustomer ("Jack");
Copy CodeChain of responsibility (responsibility chain mode)This pattern has another salutation: Control chain mode. It consists primarily of a series of processors for certain commands, each of which is passed in the processor-formed chain of responsibility, at each junction by the processor to determine if they need to be responded to and handled. Each handler pauses when the processor processes the requests.
-
- Interface Command {
- function OnCommand ($name, $args);
- }
- Class Commandchain {
- Private $_commands = Array ();
- Public Function AddCommand ($cmd) {
- $this->_commands[]= $cmd;
- }
- Public Function RunCommand ($name, $args) {
- foreach ($this->_commands as $cmd) {
- if ($cmd->oncommand ($name, $args))
- Return
- }
- }
- }
- Class Custcommand implements Command {
- Public Function OnCommand ($name, $args) {
- if ($name! = ' Addcustomer ')
- return false;
- Echo ("This is Customercommand handling ' Addcustomer ' \ n");
- return true;
- }
- }
- Class Mailcommand implements Command {
- Public Function OnCommand ($name, $args) {
- if ($name! = ' mail ')
- return false;
- Echo ("This is Mailcommand handling ' mail ' \ n");
- return true;
- }
- }
- $CC = new Commandchain ();
- $CC->addcommand (New Custcommand ());
- $CC->addcommand (New Mailcommand ());
- $CC->runcommand (' Addcustomer ', null);
- $CC->runcommand (' mail ', null);
Copy Code |