首先,我们需要了解一下什么是工厂模式,工厂模式就是用来产生对象的类或方法,包括简单工厂模式,单例工厂,工厂方法模式,抽象工厂方法和原型工厂
1.简单工厂模式
简单工厂模式一般都是通过静态方法去产生对象的,可以产生任意对象。
示例代码如下:
2.单例工厂
通过单例工厂产生的对象能被其他对象全部访问,同时也避免了如全局变量般容易被覆写的风险
示例代码:
3.工厂方法模式
假设我们现在有一个抽象创建者company类(把它当做一个公司),该类有一个工厂方法用来生产product1(可以在抽象基类中添加默认实现)
在现实生活中,一个产品一般都会对应着几个型号,这里定义了接口product1用来实现多态
假设产品1有两种型号,那么具体的类定义如下:
一个公司要生产产品,还需要一个生产计划,在这里体现为具体创建者,下面是两个具体创建者类的定义,代码如下:
到这里,我们就可以看出工厂方法模式的好处,如果需要扩展产品型号,则只需要添加product1接口的具体实现(添加新产品),然后由具体创建者创建(加入生产计划),而无需修改原代码,实现了横向的扩展。
在运用中,需要通过系统配置来决定实例化哪个具体创建者(使用哪个生产计划)。在这里展示一下具体的做法:
首先定义一个config 类,类中包含作为配置的静态变量
然后定义一个AppConfig类,这是一个标准的单例,可以全局访问,用于根据config类中的配置去实例化具体创建者(长度过截不下这里直接贴代码)
class Appconfig{
private static $app;
public $plan;
private function __construct(){
$this->init();
}
private function init(){
switch(config::$plan){
case'plan1':$this->plan=new plan1();break;
case'plan2':$this->plan=new plan2();break;
}
public static function getInstance(){
if(!isset($app) || $app instanceof Appconfig){
self::$app=new Appconfig();
}
return self::$app;
}
public function getManager(){
return $this->manager;
}
}
$obg=Appconfig::getInstance();
$obg->getManager()->ProductGroup();
通过修改config中的plan参数,我们就可以切换实例化的具体创建者(改变计划)
在现实生活中,一个公司很少只生产一种类型的产品,假设这个公司现在想生产新的产品来丰富自己的产品体系,又该怎么做呢?那么是时候介绍下一种模式——抽象工厂模式。
4.抽象工厂模式
上文所说的新产品,同样的也可能需要有多种型号来适应市场的需求,同样的,按照我们上面的思路,一个新产品需要的是能够生产它的工厂,能实现产品多样化的产品接口,和具体的生产计划,所以我们需要做的有这么几件事:在company类中添加:getProduct2()方法;添加一个新的产品接口product2;添加几个产品类去实现该接口,如product2_1,product2_2;添加具体创建者类,如plan3类,按照上面的代码去添加,在这里就不贴上代码了。在这里我们也能看到采用设计模式来设计代码所能带来的扩展方面的优势。但是到这里也许有人已经想到了一个问题,当产品日益增加,生产计划肯定越来越多,这意味着我们需要定义很多具体创建者类(制定很多生产计划),想到这就想狗带了。为了减少具体创建者的创建,该亮出大宝剑了——原型模式
5.原型模式
原型模式的思路是在初始化的时候就保存了具体产品类,然后在需要生产对象的时候通过clone已经存在的产品去产生对象,利用该模式可以用组合代替继承,提高了代码的灵活性,减少了创建的类的数量,但需要注意的一点是如果产品类属性里面包含对象属性,一般我们需要进行深克隆,关于deep clone和shallow clone的东西由于不是本篇文章的重点,请不清楚的读者自己去google一下。
写在最后,作者本人其实也是个小白,第一次提笔写下学习笔记,希望各位多多鼓励一下,文中用产品,生产计划等概念是为了帮助理解,如果文中有不恰当的地方欢迎指出,共同进步~~~