设计模式
使用设计模式是
促进最佳实践和良好设计的好办法。设计模式可以提供针对常见的编程问题的灵活的解决方案。
工厂方法模式
这种设计模式网上可以查阅的资源有很多,但是很多都是理论性太强,理解起来不是很容易,首先我们先看一下,这种模式是如何定义的?使用的场景是什么?
定义
:定义一个创建对象的接口,但是让
子类去实例化具体类。
工厂方法模式让类的实例化
延迟到子类中。针对每一种产品提供一个工厂类,通过不同的工厂实例来创建不同的产品实例,在同一等级结构中,支持增加任意产品。
问题引出:框架需要为多个应用提供
标准化的架构模型,同时也要
允许独立应用定义自己的域对象并对其进行实例化。
1 类的实现
工厂方法模式包含如下角色:
抽象产品(Product)角色:具体产品对象共有的父类或接口
具体产品(Concrete Product)角色:实现抽象产品角色所定义的接口,并且工厂方法模式所创建的每一个对象都是某具体产品对象的实例
抽象工厂(Creator)角色:模式中任何创建对象的工厂类都要实现这个接口,它声明了工厂方法,该方法返回一个Product类型的对象。
代码实例:
# 创建抽象工厂角色
interface Creator {
public function factoryMethod(); # 定义一个工厂方法
}
# 创建具体的工厂角色A,并继承抽象工厂角色(Creator )
class ConcreteCreatorA implements Creator {
/**
* 实现工厂方法factoryMethod 返回具体产品ConcreteProductA
* @return ConcreteProductA
*/
public function factoryMethod() {
return new ConcreteProductA();
}
}
# 创建具体的工厂角色B,并继承抽象工厂角色(Creator )
class ConcreteCreatorB implements Creator {
/**
* 实现工厂方法factoryMethod 返回具体产品ConcreteProductB
* @return ConcreteProductB
*/
public function factoryMethod() {
return new ConcreteProductB();
}
}
上面的代码有了抽象工厂,具体工厂角色,下面我们需要定义一个抽象产品角色
# 定义一个抽象产品角色
interface Product {
public function operation();
}
# 具体的产品角色A
class ConcreteProductA implements Product {
/**
* 接口方法实现 输出特定字符串
*/
public function operation() {
echo 'ConcreteProductA <br />';
}
}
# 具体的产品角色B
class ConcreteProductB implements Product {
/**
* 接口方法实现 输出特定字符串
*/
public function operation() {
echo 'ConcreteProductB <br />';
}
}
# 定义一个静态方法去调用它
class Client {
/**
* Main program.
*/
public static function main() {
$creatorA = new ConcreteCreatorA();
$productA = $creatorA->factoryMethod();
$productA->operation();
$creatorB = new ConcreteCreatorB();
$productB = $creatorB->factoryMethod();
$productB->operation();
}
}
# 调用方式
Client::main(); # 或者以传参数的方式去调用
# 输出结果
ConcreteProductA
ConcreteProductB
2 结论
看到这里,我们在回头去看之前得出的结论:
1、针对
每一种产品提供
一个工厂类,通过
不同的工厂实例来创建不同的产品实例,在同一等级结构中,支持增加任意产品。
2、工厂方法模式之所以有一个别名叫
多态性工厂模式是因为具体工厂类都有
共同的接口,或者有共同的抽象父类。
3、当系统扩展需要
添加新的产品对象时,仅仅需要添加一个具体对象以及一个具体工厂对象,原有工厂对象不需要进行任何修改,也不需要修改客户端,
很好的符合了”开放-封闭”原则。
3 扩展
工厂方法模式的
优点:
工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品。
工厂方法模式的
缺点:
客户可能仅仅为了创建一个特定的ConcreteProduct对象,就不得不创建一个Creator子类
4 图解
***解析***
1、首先定义两个抽象的类Greator、Product
2、在两个抽象类下面分别定义两个具体类A、B
3、当我们去调用抽象工厂角色Greator下面的具体工厂角色ConcreteGreatorA时,返回抽象产品角色Product下的具体产品角色ConcreteProductA的实例,并执行其中的operation()方法
由此可见:当我们需要添加C产品时,只需要在抽象工厂角色Greator下面创建一个具体产品角色C,在抽象产品角色Product下创建一个具体产品角色C就可以了
,扩展性很好,不需要修改原有代码
。
更多设计模式文章请点击下面链接:
【设计模式概述】 http://blog.youkuaiyun.com/bk_guo/article/details/73828064
【简单工厂模式】 http://blog.youkuaiyun.com/bk_guo/article/details/73849317
【单例模式】 http://blog.youkuaiyun.com/bk_guo/article/details/73845244