一、单例模式
通俗地说就是实例化出来的对象是唯一的。
所有的单例模式至少拥有以下三种公共元素:
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缓存的道理是一样的。
网友评论