PHP单例模式、工厂模式、注册模式

2019-03-14  本文已影响0人  叶惜朝

一、单例模式

通俗地说就是实例化出来的对象是唯一的。

所有的单例模式至少拥有以下三种公共元素:

1. 它们必须拥有一个构造函数,并且必须被标记为private

2. 它们拥有一个保存类的实例的静态成员变量

3. 它们拥有一个访问这个实例的公共的静态方法

单例类不能再其它类中直接实例化,只能被其自身实例化。它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用。

class Database

{

  //定义一个属性,该属性是静态的保护或私有属性

  protected static $db;

  //这里构造函数一定要是私有方法

  private function __construct()

  { 

    }

  //声明一个获取类实例的方法

  static function getInstace()

  { 

      if(self::$db) {

          return self::$db;

      }else {

          //生成自己

          self::$db = new self();

          return self::$db;

      } 

    }

}

//错误调用方法

//用new实例化private标记构造函数的类会报错

$db = new Database();

//正确获取实例方法

$db = Database::getInstace();

1.构造函数需要标记为private(访问控制:防止外部代码使用new操作符创建对象),单例类不能在其他类中实例化,只能被其自身实例化;

2.拥有一个保存类的实例的静态成员变量;

3.拥有一个访问这个实例的公共的静态方法(常用getInstance()方法进行实例化单例类,通过instanceof操作符可以检测到类是否已经被实例化);

4.如果严谨的话,还需要创建__clone()方法防止对象被复制(克隆)。

二、工厂模式

1、当我要实例化类的时候,不直接new这个类,而是通过调用另一个类的一个方法来实例化。这就是工厂模式的核心原理。

class Factory { //创建一个基本的工厂类

      static public function fac($id){//创建一个返回对象实例的静态方法

          if(1 == $id) return new A();

          elseif(2==$id) return new B();

          elseif(3==$id) return new C();

          return new D();

      }

  }

interface FetchName {//创建一个接口

    public function getname();//

}

class A implements FetchName{

    private $name = "AAAAA";

    public function getname(){ return $this->name; }

}

class C implements FetchName{

    private $name = "CCCCC";

    public function getname(){ return $this->name; }

}

class B implements FetchName{

    private $name = "BBBBB";

    public function getname(){ return $this->name; }

}

class D implements FetchName{

    private $name = "DDDDD";

    public function getname(){ return $this->name; }

}

$o = Factory::fac(6);//调用工厂类中的方法

if($o instanceof FetchName){

  echo  $o->getname();//DDDDD

}

$p=Factory::fac(3);

echo $p->getname();//CCCCC

三、注册模式

注册模式在单例模式的基础上进一步拓展了一步,他把所有单例模式的对象全部保存在一个索引数组中,下次取得时候,直接去数组里按照索引去取。

这样的好处是在程序中有条理的存放并管理对象。所以,肯定有一个存(set)和一个取(get)。一般是先去取如果没有,就重新初始化然后存起来,这样这个周期中的其他代码就可以直接取了。和redis缓存的道理是一样的。

上一篇下一篇

猜你喜欢

热点阅读