zoukankan      html  css  js  c++  java
  • 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()这样的方式实例化子类。

  • 相关阅读:
    acwing2-01背包问题
    背包问题(转载)
    考研易错点 二叉树的度和图的度
    考研易错点*s++
    考研复习易错点数组指针和指针数组
    Android Crash Learning
    Mysql5.7中的分组排序
    康师傅JVM:StringTable(十三)
    RocketMQ集群搭建
    RocketMq的单机安装
  • 原文地址:https://www.cnblogs.com/feixiablog/p/8795174.html
Copyright © 2011-2022 走看看