注册 登录

清河洛

OOP中的单例模式工厂模式和类型约束

qingheluo2016-12-16清河洛235
单例模式:一个类可以实例化无数个对象,但是有些情况下一个类的一个实例对象就可以完成所有功能(如数据库连接类)这时就需要限制该类可以实例化多个对象,可以节省开销(如内存,运行时间)这种设计称之为单例模式(也称为数据库模式,因为使用这个模式的最多的地方一般就是数据库)三私一公的类内实现单例设计:class MySQLDB{ private function __construct(){} private static $_job; private function __clone(){} public static function getMysqlJob()...

单例模式:

一个类可以实例化无数个对象,但是有些情况下一个类的一个实例对象就可以完成所有功能(如数据库连接类)

这时就需要限制该类可以实例化多个对象,可以节省开销(如内存,运行时间)

这种设计称之为单例模式(也称为数据库模式,因为使用这个模式的最多的地方一般就是数据库)

三私一公的类内实现单例设计

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会检测传入参数是否是数组类型



网址导航