• PHP设计模式单例模式的继承实现


    最近在做O2O平台的接入,因为发现之前公司的代码里已经有了某家开放平台的接入代码,如果我再往原先的控制器上加入逻辑代码,整个控制器的耦合度会非常高。加上每个平台有自己的签名验证算法,把加解密的方法写到平台的接入控制器里固然好,但是还是有耦合度问题。因此我的做法是先实现目前手上需要的功能,稍后会用面向对象的方法写一个抽象类,然后用对应平台的子类实现相应平台所需要的业务逻辑代码。

    在写的过程中,发现现在框架中使用的YiiMongoDbSuite为模型类实现的一个单例模式很有意思,遂决定使用同样的写法实现我所需要的平台接入类。在这里我将这种写法略微总结一下。为了方便,例子中的变量名都使用YiiMongoDbSuite拓展中的变量名了。

    1.父类(抽象类)中定义一个私有的静态变量$_model,类型为数组,用来保存子类实例化后的结果。

    2.父类实现一个静态的公共函数model(),用于生成子类的实例化并保存在$_model,传参为类名__CLASS__

    3.子类中同样实现静态公共函数model(),直接返回继承的父类的model()方法结果。

    具体还是看实现的代码。

    父类(抽象类):

    <?php

    abstract class Father {

      public function __construct() {}

      private static $_models = array();

      public static function model($className = __CLASS__) {

        if (isset(self::$_models[$className])) {

          return self::$_models[$className];

        }else {

          $model = self::$_models[$className] = new $className(null); return $model;

        }

      }

    }

    子类:

    <?php class Child extends Father {

      public static function model($className=__CLASS__) {

        return parent::model($className);

      }

      public function test() {

      echo 'i am child!'." ";

      }

    }

    测试代码:

    <?php

    var_dump(Child::model());

    Child::model()->test();

    // 尝试用同样的方法生成一个实例并打印

    var_dump(Chils::model());

    // 直接用new关键字生成一个实例并打印

    var_dump(new Child());

    结果:

    object(Putao)#1 (0) {}

    i am child!

    object(Putao)#1 (0) {}

    object(Putao)#2 (0) {}

    可以注意到,使用Child::model()生成的实例ID相同,而直接通过new Child()生成的实例ID为2

    当然,也可以把父类的__constract()方法改为私有方法,这样new关键字就失效了,只能通过Child::model()这样的方式实例化子类。

  • 相关阅读:
    ReentrantLock的实现语义与使用场景
    队列同步器详解
    设计模式--模板方法模式
    Synchronized及其实现原理
    JAVA线程基础
    JAVA内存模型
    java 线上问题定位工具
    JMX超详细解读
    Hexo
    [转]html5 video在安卓大部分浏览器包括微信最顶层的问题
  • 原文地址:https://www.cnblogs.com/feixiablog/p/8795174.html
Copyright © 2020-2023  润新知