欢迎光临杨雨的个人博客站!

杨雨个人网站-杨雨个人博客-杨照佳

杨雨个人博客网站

关注互联网和搜索引擎的个人博客网站

首页 > WEB开发 > PHP >

PHP中的计划模式

发布时间:2016-11-24  编辑:杨雨个人博客网站   点击:   

  本文首要接头下Web开拓中,精确而言,是PHP开拓中的相干的计划模式及其应用。有履历的开拓者必定对付计划模式很是认识,可是本文首要是针对那些低级的开拓者。起首我们要搞清晰到底什么是计划模式,计划模式并不是一种用来表明的模式,它们并不是像链表那样的常见的数据布局,也不是某种非凡的应用可能框架计划。究竟上,计划模式的表明如下:

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

PHP中的打算模式

  另一方面,计划模式提供了一种普及的可重用的方法来办理我们一般编程中经常碰见的题目。计划模式并不必然就是一个类库可能第三方框架,它们更多的示意为一种头脑而且普及地应用在体系中。它们也示意为一种模式可能模板,可以在多个差异的场景下用于办理题目。计划模式可以用于加快开拓,而且将许多大的设法可能计划以一种简朴处所式实现。虽然,固然计划模式在开拓中很有浸染,可是万万要停止在不恰当的场景误用它们。

  今朝常见的计划模式首要有23种,按照行使方针的差异可以分为以下三大类:

  • 建设模式:用于建设工具从而将某个工具从实现中解耦合。

  • 架构模式:用于在差异的工具之间结构大的工具布局。

  • 举动模式:用于在差异的工具之间打点算法、相关以及职责。

 Creational Patterns

  Singleton(单例模式)

  单例模式是最常见的模式之一,在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)

  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

  Factory(工场模式)

  工场模式是另一种非经常用的模式,正如其名字所示:确实是工具实例的出产工场。某些意义上,工场模式提供了通用的要领有助于我们去获取工具,而不必要体谅其详细的内涵的实现。

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

  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

  Object pool(工具池)

  工具池可以用于结构而且存放一系列的工具并在必要时获取挪用:

<?php

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

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

  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

  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

  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

 Structural Patterns

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

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

 Behavioral Patterns

  Strategy(计策模式)

  测试模式首要为了让客户类可以或许更好地行使某些算法而不必要知道其详细的实现。

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

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

  Chain of responsibility(责任链模式)

  这种模式有另一种称号:节制链模式。它首要由一系列对付某些呼吁的处理赏罚器组成,每个查询会在处理赏罚器组成的责任链中转达,在每个交汇点由处理赏罚器判定是否必要对它们举办相应与处理赏罚。每次的处理赏罚措施会在有处理赏罚器处理赏罚这些哀求时停息。

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

  原文地点:Design Patterns in PHP

本文地址:http://itbyc.com/php/13184.html
转载请注明出处。
分享是一种快乐,也是一种美德:
评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
博客首页 | WEB开发 | 网站运营 | CMS使用教程 滇ICP备14002061号-1