OOP中的单例模式工厂模式和类型约束
单例模式:
一个类可以实例化无数个对象,但是有些情况下一个类的一个实例对象就可以完成所有功能(如数据库连接类)
这时就需要限制该类可以实例化多个对象,可以节省开销(如内存,运行时间)
这种设计称之为单例模式(也称为数据库模式,因为使用这个模式的最多的地方一般就是数据库)
三私一公的类内实现单例设计:
class MySQLDB{
private function __construct(){}
private static $_job;
private function __clone(){}
public static function getMysqlJob(){
if(!isset(static::$_job)){
static::$_job==new static();
}
return static::$_job;
}
}
构造方法使用的私有化(private)限制符,使用常规的new实例化时自动调用构造方法会报错,从而实例化失败,防止该类可以实例化多个对象
定义私有静态变量$_job和公共静态方法getMysqlJob()
getMysqlJob()函数中会判断$_job的值是否为NULL(即没有实例化过),如果为NULL则实例化该类,由于是在类内实例化,所以可以访问构造方法,实例化会成功
如果$_job已经存在一个对象,那么不实例化该类直接返回$_job的对象,这样多次实例化也只会实例化一个对象
$MySQLDB=MySQLDB::getMysqlJob();
克隆方法使用私有化限制符来防止对象克隆导致多个对象的产生
类外实现单例模式的效果(并不是严格意义上的单例模式,仅仅是实现了效果)
function getJob($class_name){
static $job_list=array();
if(!isset($job_list[$class_name])){
$job_list[$class_name]=new $class_name();
}
return $job_list[$class_name];
}
这种方法并没有从根本上解决单例问题(仍可使用new来实例化多个对象),但是优势很明显,比较灵活,不需要改变类本身,同时能适用多个类
但是这个是面向过程,我们使用面向对象开发的时候虽然这样能实现单例的效果,但是一般不使用这样的方式,而使用工厂模式
工厂模式:
从类的功能上讲,如果某个类的主要功能就是用来生产其他类的对象,这样的类称之为工厂类
由于工厂类一般情况下不需要自身实例化对象,所以一般工厂类的成员都设置为静态成员,所以工厂类又被称为静态工厂
class Factory{
public static function getJob($class_name){
static $job_list=array();
if(!isset($job_list[$class_name])){
$job_list[$class_name]=new $class_name();
}
return $job_list[$class_name];
}
}
仅仅通过new去实例化对象,有时候不能满足某些实际的业务逻辑,比如说单例模式,所以需要工厂
类型约束:
类型约束是约束方法参数数据类型的一种语法
class Ajob{ public function fun01(Bjob $job){} }
上面例子中Ajob类中的方法fun01的参数前面加了Bjob限制条件,表示该方法调用时传入的参数$job必须是Bjob类或Bjob类的子类所实例化的对象,传入其他会报错
注意点:
class Ajob{ public function fun01(String $job){} }
上例中方法在调用时php会寻找名称为String的类,如果该类存在,那么检测$job是否是该类的一个实例对象,而此时传入参数如果为字符串那么由于字符串并不是对象,会报错,int、bool等数据类型同理
但是php中有一个特例,就是数组类型array,当限制条件为array时php会检测传入参数是否是数组类型