乘风原创程序

  • 深入分析PHP设计模式
  • 2020/6/15 15:06:09
  • 1、单例模式

    一个类,只能允许有一个对象存在

    <?php
    class test{
      protected function __construct(){
      }
    
      public static function getInstance(){
        $_test = new test();
        return $_test;
      }
    }
    $test = test::getInstance();
    var_dump($test);
    ?>

    2、工厂模式

    工厂模式,顾名思义,如同工厂一样,你把原材料放入工厂中,出来的是成品,而你并不需要知道工厂里做了什么,工厂模式主要用于解耦。

    把对象的创建和使用的过程分开,比如: ClassA 调用 ClassB,那么 ClassA 只调用ClassB 的方法,
    至于实例化 ClassB 则在工厂内实现。这样既减少了代码的重复使用,也方便对 ClassB 的后期维护。
    如果 ClassB 实例化过程很复杂,使用简单工厂模式就会发现外部无需关注复杂的实例化,只管调用 ClassB 的方法即可,减少错误

    interface mysql{ 
      public function connect();
    }
     
    class mysqli2 implements mysql{
      public function connect(){
        echo 'mysqli';
      }
    }
     
    class pdo2 implements mysql{
      public function connect(){
        echo 'pdo';
      }
    }
    
    class mysqlFactory{
      static public function factory($class_name){
        return new $class_name();
      }
    }
    $obj = mysqlFactory::factory('pdo2');
    $obj->connect();

    3、注册模式

    注册模式,解决全局共享和交换对象。已经创建好的对象,挂在到某个全局可以使用的数组上,

    在需要使用的时候,直接从该数组上获取即可。将对象注册到全局的树上。任何地方直接去访问。

    <?php
    class Register
    {
        protected static $objects;
        function set($alias,$object)//将对象注册到全局的树上
        {
          self::$objects[$alias]=$object;//将对象放到树上
        }
        static function get($name){
          return self::$objects[$name];//获取某个注册到树上的对象
         }
      function _unset($alias)
      {
         unset(self::$objects[$alias]);//移除某个注册到树上的对象。
        }
    }
    
    \Auto\Register::set('single',$single);
    $single = \Auto\Register::get('single');
    var_dump($single);

    4、适配器模式

    将一个类的接口转换成客户希望的另外一个接口。

    //目标角色
    interface Aims
    {
      public function newMethod1();
      public function newMethod2();
    }
     
    //需要被适配的类(Adaptee)
    Class Man
    {
      public function oldMethod1()
      {
        echo 'man';
      }
     
      public function oldMethod2()
      {
        echo '男人';
      }
    }
     
    //需要被适配的类(Adaptee)
    Class Woman
    {
      public function oldMethod1()
      {
        echo 'woman';
      }
     
      public function oldMethod2()
      {
        echo '女人';
      }
    }
     
    //适配器,
    Class Adapters implements Aims
    {
      private $adaptee;
      public function __construct($adaptee)
      {
        $this->adaptee = $adaptee;
      }
     
      public function newMethod1()
      {
        //以少量的代码对被适配者作出适配
        echo 'sex :';
        $this->adaptee->oldMethod1();
      }
     
      public function newMethod2()
      {
        echo 'sex name :';
        $this->adaptee->oldMethod2();
      }
    }
     
    $adapter1 = new Adapters(new Man);
    $adapter1->newMethod1();
    $adapter2 = new Adapters(new Woman);
    $adapter2->newMethod2();

    5、策略模式

    这是一个男人和女人的问题,将一组特定的行为和算法封装成类,以适应某些特定的上下文环境。

    UserStrategy.php
    <?php
    /*
     * 声明策略文件的接口,约定策略包含的行为。
     */
    interface UserStrategy
    {
      function showAd();
      function showCategory();
    }
    
    FemaleUser.php
    <?php
    class FemaleUser implements UserStrategy
    {
      function showAd(){
        echo "2016冬季女装";
      }
      function showCategory(){
        echo "女装";
      }
    }
    
    MaleUser.php
    <?php
    class MaleUser implements UserStrategy
    {
      function showAd(){
        echo "IPhone6s";
      }
      function showCategory(){
        echo "电子产品";
      }
    }
    
    Page.php//执行文件
    <?php
    require_once 'Loader.php';
    class Page
    {
      protected $strategy;
      function index(){
        echo "AD";
        $this->strategy->showAd();
        echo "<br>";
        echo "Category";
        $this->strategy->showCategory();
        echo "<br>";
      }
      function setStrategy(UserStrategy $strategy){
        $this->strategy=$strategy;
      }
    }
    
    $page = new Page();
    if(isset($_GET['male'])){
      $strategy = new MaleUser();
    }else {
      $strategy = new FemaleUser();
    }
    $page->setStrategy($strategy);
    $page->index();

    6、原型模式

    不常用,大的对象类才使用,表现在clone

    7、观察者模式

    从面向过程的角度来看,首先是观察者向主题注册,注册完之后,主题再通知观察者做出相应的操作,整个事情就完了

    /**
     * 事件产生类
     * Class EventGenerator
     */
    abstract class EventGenerator
    {
      private $ObServers = [];
    
      //增加观察者
      public function add(ObServer $ObServer)
      {
        $this->ObServers[] = $ObServer;
      }
    
      //事件通知
      public function notify()
      {
        foreach ($this->ObServers as $ObServer) {
          $ObServer->update();
        }
      }
    
    }
    
    /**
     * 观察者接口类
     * Interface ObServer
     */
    interface ObServer
    {
      public function update($event_info = null);
    }
    
    /**
     * 观察者1
     */
    class ObServer1 implements ObServer
    {
      public function update($event_info = null)
      {
        echo "观察者1 收到执行通知 执行完毕!\n";
      }
    }
    
    /**
     * 观察者1
     */
    class ObServer2 implements ObServer
    {
      public function update($event_info = null)
      {
        echo "观察者2 收到执行通知 执行完毕!\n";
      }
    }
    
    /**
     * 事件
     * Class Event
     */
    class Event extends EventGenerator
    {
      /**
       * 触发事件
       */
      public function trigger()
      {
        //通知观察者
        $this->notify();
      }
    }
    
    //创建一个事件
    $event = new Event();
    //为事件增加旁观者
    $event->add(new ObServer1());
    $event->add(new ObServer2());
    //执行事件 通知旁观者
    $event->trigger();