MrZyb Always in fear of one's own ignorance
  • 单例模式
    • 核心思想:在Web应用的开发中,常常用于允许在运行时为某个特定的类创建仅有一个可访问的实例。
    • 例子:在使用实例化Mysql操作类进行数据操作时可以使用该模式,避免在开发过程中造成不必要的开销。要获取类实例时只能通过Singleton::getInstance()来获取。
      <?php
      final class Singleton
      {
      private static $instance;
      /** 构造函数为private,防止创建对象 **/
      private function __construct(){}
      /** 防止对象被复制 **/
      private function __clone(){}
      /** 防止对象被序列化 **/
      private function __wakeup(){}
      public static function getInstance()
      {
         if (! (self::$instance instanceof self)) self::$instance = new self();
         return self::$instance;
      }
      }
  • 多例模式

    • 核心思想:多例模式与单例模式相类似。在多例模式中,多例类可以同时拥有有限个实例,但是这些实例必须由多例类自己创建和管理,并通过特定的方法对外提供自己的实例,外界只拥有使用的权利。多例模式可以认为是一种特殊的单例状态,可以看作这个单例被创建了多次且能实现对这些实例的管理。
    • 例子:多例模式的多数据库连接

      <?php
      class Multiton
      {
      private static $instances = [];
      private function __construct(){}
      private function __clone(){}
      private function __wakeup(){}
      
      private static $config = [
         'redis_master' => [
             '1' => ['host' => '127.0.0.1', 'port' => 4025],
         ],
         'redis_slave' => [
             '1' => ['host' => '127.0.0.1', 'port' => 4020],
         ],
         'mysql' => [
             'write_master' => ['host' => '127.0.0.1', 'port' => 3306, 'user' => 'sb', 'passwd' => 'sbsbdsb', 'db' => 'test'],
         ],
      ];
      
      public static function getInstance($instanceName, $confKey = '')
      {
         $curInstanceName = $instanceName . $confKey;
      
         if (!isset(self::$instances[$curInstanceName])) {
             $config = self::$config;
             if (!isset($config[$instanceName][$confKey]) || empty($config[$instanceName][$confKey])) return false;
             $initConf = $config[$instanceName][$confKey];
             switch ($instanceName) {
                 case 'redis_master':
                 case 'redis_slave':
                         $redis = new redis;
                         $redis->pconnect($initConf['host'], $initConf['port']);
                         self::$instances[$curInstanceName] = $redis;
                     break;
                 case 'mysql':
                         $db = new mysqli($initConf['host'],  $initConf['user'],  $initConf['passwd'],  $initConf['db'], $initConf['port']);
                         $db->query("SET NAMES UTF8MB4");
                         self::$instances[$curInstanceName] = $db;
                     break;
                 case 'memcache':
                         $memcache = new Memcached;
                         $memcache->addServer($initConf['host'], $initConf['port']);
                         self::$instances[$curInstanceName] = $memcache;
                     break;
                 default:
                     break;
             }
         }
         return self::$instances[$curInstanceName];
      }
      }
    • 传送门:
  • 工厂模式
  • 建造者模式

    • 核心思想:建造者模式主要在于创建一些复杂的对象。将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示的设计模式。建造者模式组成:导演类(产品属性的设置);基础属性类(初始化产品属性);抽象产品类(设定统一的属性设置方法);具体产品类(通过已经设定好的方法设置具体的产品属性值)。
    • 例子:用建造者创建不同的游戏角色实现。每个游戏英雄构造体系有一个总体的基础属性类,然后有一个导演在规划这整个布局(导演类),导演类通过对具体的英雄类(具体产品类)的创造(实例化)来实现对不同类别的英雄的具体数据的设置,而英雄类(具体产品类)又是继承与相同的类(抽象类)的,所以他们身上都是有着共同属性的。

      
      <?php
      /** 游戏英雄属性 **/
      class Hero {
      public $role;
      public $name;
      public $sex;
      public $power;
      public function __construct($name, $sex) {
         $this->name = $name;
         $this->sex = $sex;
      }
      }
      /** 建造者抽象类 **/
      abstract class HeroBuilder {
      public $hero;
      public function __construct(Hero $hero) {
         $this->hero = $hero;
      }
      public abstract function setRole();
      public abstract function setPower();
      
      public function getHero() {
         return $this->hero;
      }
      }
      /** 具体的刺客类 **/
      class AssassinBuilder extends HeroBuilder {
      public function setRole(){
         $this->hero->role = '刺客';
      }
      public function setPower(){
         $this->hero->power = '1000';
      }
      }
      /** 具体的战士类 **/
      class SoldierBuilder extends HeroBuilder {
      public function setRole(){
         $this->hero->role = '战士';
      }
      public function setPower(){
         $this->hero->power = '500';
      }
      }

    class Director { private $builder; public function __construct(HeroBuilder $builder) { $this->builder = $builder; } public function build() { $this->builder->setRole(); $this->builder->setPower(); } }

    $assassin = new AssassinBuilder(new Hero('荆轲', '男')); $director = new Director($assassin); $director->build(); $hero = $assassin->getHero(); print_r($hero);

    $assassin = new AssassinBuilder(new Hero('娜可露露', '女')); $director = new Director($assassin); $director->build(); $hero = $assassin->getHero(); print_r($hero);

    Hero Object ( [role] => 刺客 [name] => 荆轲 [sex] => 男 [power] => 1000 ) Hero Object ( [role] => 刺客 [name] => 娜可露露 [sex] => 女 [power] => 1000 )

  • 原型模式

    • 核心思想:原型模式就是用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等,通过原型拷贝避免这些消耗。 (实例化过程比较复杂的类才会使用这个)
    • 例子:简单实现。请看代码。简单来说就是返回clone一个自己。
      
      <?php
      Abstract class Prototype {
      abstract public function copy();
      }

    class TestPrototype extends Prototype { private $_instance; public function __construct($class) { $this->_instance = $class; } public function copy() { return clone $this; } }

  • 适配器模式

    • 核心思想:适配器通过将原始接口进行转换,给接口调用方提供一个通用的兼容接口,使得原来因为接口不同而无法一起使用的类可以得到兼容,减少接口调用方代码修改的成本。这个过程对接口调用方来说透明的。
    • 例子:可以通过使用Mysql类或者Mysqli来达到数据操作的目的,但是Mysql类和Mysqli类的操作方法是有差别的,这时候为了让我们在调用的时候感觉是没有差别的,可以定义一个标准接口 Interface Db,包含对数据库的基本操作,然后使用数据库时只要实例化对应的MysqlDb类或者MysqliDb类,但是实际调用的时候使用的方法都是没有差别的。
      
      <?php
      Interface Db
      {
      public function connect($host, $uname, $passwd, $database);
      public function query($sql);
      public function close();
      }

    class MysqlDb implements Db { private $db; public function connect($host, $uname, $passwd, $database) { $db = mysql_connect($host, $uname, $passwd); mysql_select_db($database, $db); $this->db = $db; } public function query($sql) { return mysql_query($sql); } public function close() { return mysql_close($this->db); } }

    class MysqliDb implements Db { private $db; public function connect($host, $uname, $passwd, $database) { $db = new mysqli($host, $uname, $passwd, $database); $this->db = $db; }

    public function query($sql) { return $this->db->query($sql); }

    public function close() { return $this->db->close($this->db); } }

    
    - 传送门
      - [DesignPatternsPHP 适配器模式](https://designpatternsphp.readthedocs.io/zh_CN/latest/Structural/Adapter/README.html)
  • 桥接模式

    • 核心思想:解耦一个对象的实现与抽象,这样两者可以独立地变化。
    • 例子:见代码。
      
      <?php
      abstract class Color {
      private $color;
      public abstract function getColor();
      }

    class Red extends Color { private $color = 'red'; public function getColor() { return $this->color; } }

    class Green extends Color { private $color = 'green'; public function getColor() { return $this->color; } }

    abstract class Shape { public function __construct(Color $color) { $this->color = $color->getColor(); } public abstract function draw(); }

    class Circle extends Shape { public function draw() { echo 'draw a circle using ' . $this->color . PHP_EOL; } }

    class Rectangle extends Shape { public function draw() { echo 'draw a rectangle using ' . $this->color . PHP_EOL; } } // 调用 $circle = new Circle(new Red()); $circle->draw(); $circle = new Circle(new Green()); $circle->draw();

    
    - 传送门:
      - [DesignPatternsPHP 桥接模式](https://designpatternsphp.readthedocs.io/zh_CN/latest/Structural/Bridge/README.html)
  • 数据映射器
  • 责任链
  • 迭代器
0.003413s