Lazy Initialization(延迟最早化卡塔尔

对于有个别变量的延迟初始化也是常常被用到的,对于贰个类来讲往往并不知道它的哪些意义会被用到,而有个别功用往往是单纯被亟需选取三次。

<?php

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

Singleton(单例方式State of Qatar

单例形式是最广泛的方式之生机勃勃,在Web应用的开垦中,日常用于允许在运维时为有些特定的类创立二个可访谈的实例。

<?php
/**
 * 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

在非常多动静下,需求为系统中的多少个类创造单例的组织情势,那样,能够创设一个通用的悬空父工厂方法:

<?php

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)

Behavioral Patterns

Structural Patterns

  • 创建情势:用于创制对象进而将有个别对象从落实中解耦合。
  • 构造方式:用于在差别的指标时期布局大的靶子协会。
  • 表现方式:用于在不一样的靶子时期管清理计算法、关系以至职务。

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 onChanged($sender, $args) {
    echo( "'$args' Customer has been added to the list \n" );
  }
}

$ul = new UserList();
$ul->addObserver( new CustomerListLogger() );
$ul->addCustomer( "Jack" );

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();
    }
}

// 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."<br/>";
}

descriptions of communicating objects and classes that are customized
to solve a general design problem in a particular context.

Strategy(攻略形式State of Qatar

测验方式主要为了让顾客类能够更加好地选拔一些算法而没有必要驾驭其实际的实现。

<?php

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;
    }
}

Object pool(对象池)

对象池能够用来组织何况贮存一文山会海的指标并在需求时得到调用:

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::pushProduct(new Product('first'));
Factory::pushProduct(new Product('second'));

print_r(Factory::getProduct('first')->getId());
// first
print_r(Factory::getProduct('second')->getId());
// second

Prototype(原型方式卡塔尔(قطر‎

多少时候,部分目的急需被初步化多次。而极其是在假若开始化需求花费多量日子与能源的时候进行预伊始化何况存款和储蓄下那个目的。

<?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

Registry

注册台形式并非很宽泛,它亦非二个天下无敌的成立方式,只是为着接受静态方法更有益于的存取数据。

<?php
/**
* 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

一面,设计格局提供了豆蔻梢头种不以为奇的可采纳的不二等秘书诀来消除大家平时编制程序中有时碰着的难点。设计格局并不一定正是二个类库也许第三方框架,它们越多的显示为风华正茂种思想何况遍布地选拔在系统中。它们也展现为豆蔻梢头种格局大概模板,能够在多少个分歧的风貌下用于解决难点。设计形式能够用于加快开拓,何况将繁多大的主见如故安顿以黄金时代种简单地办法完毕。当然,即便设计形式在付出中很有效果与利益,可是应当要幸免在不合适的气象误用它们。

Creational Patterns

正文主要研商下Web开辟中,精确来讲,是PHP开垦中的相关的设计情势会同应用。有经验的开拓者肯定对于设计形式非常熟稔,不过本文首假设针对那个低档的开采者。首先大家要搞明白终归什么是设计格局,设计格局并非大器晚成种用来分解的格局,它们并非像链表那样的周边的数据构造,亦非某种特殊的选用也许框架设计。事实上,设计格局的解释如下:

AbstractFactory(抽象工厂情势卡塔尔国

稍稍境况下我们供给依照差别的挑精拣肥逻辑提供差别的组织工厂,而对于多少个工厂来说要求叁个统后生可畏的虚幻工厂:

<?php

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

Decorator(装饰器方式卡塔尔(قطر‎

装饰器方式允许我们根据运维时分歧的风貌动态地为有个别对象调用前后加多分裂的行事动作。

<?php
class HtmlTemplate {
    // any parent class methods
}

class Template1 extends HtmlTemplate {
    protected $_html;

    public function __construct() {
        $this->_html = "<p>__text__</p>";
    }

    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("<h2>" . $this->_html . "</h2>");
    }

    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("<u>" . $this->_html . "</u>");
    }

    public function __call($name, $args) {
        $this->_element->$name($args[0]);
    }
}

当前遍布的设计形式重要有23种,遵照使用对象的差异足以分为以下三大类:

Factory(工厂方式State of Qatar

工厂形式是另风流倜傥种异平时用的情势,正如其名字所示:确实是目的实例的生育工厂。某个意义上,工厂情势提供了通用的方法带动大家去获得对象,而无需关心其现实的内在的兑现。

<?php

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

Builder(构造者)

构造者形式首要在于创立一些错落有致的对象:

<?php

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

Chain of responsibility(义务链方式卡塔尔(قطر‎

这种格局有另朝气蓬勃种名称为:调控链情势。它最首要由风流倜傥星罗棋布对于一些命令的拍卖器构成,各种查询会在微电脑构成的义务链中传递,在种种交汇点由Computer判定是不是需求对它们实行响应与管理。每一趟的处理程序会在有计算机管理这一个哀求时停顿。

<?php

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);

Author

发表评论

电子邮件地址不会被公开。 必填项已用*标注