一、首先学术一下:
(以下内容来自:设计模式 可复用面向对象软件的基础 Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides 著 李英军 马晓星 蔡敏 刘建中 等译 吕建 审校)
抽象工厂模式: abstract factory
1 意图
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类
2 适用性
1. 一个系统要独立于它的产品的创建、组合和表示时
2. 一个系统要由多个产品系列中的一个来配置时
3. 当你要强调一系列相关的产品对象的设计以便进行联合使用时
4. 当你提供一个产品类库,而只想显示它们的接口而不是实现时
3 参与者
AbstractFactory: 声明一个创建抽象产品对象的操作接口
ConcreteFactory: 实现创建具体产品对象的操作
AbstractProduct: 为一类产品对象声明一个接口
ConcreteProduct:定义一个将被相应的具体工厂创建的产品对象;实现 AbstractProduct接口
4 协作
1)运行时创建一个ConcreteFactory类的实例。为创建不同的产品对象,客户应使用不同的具体工厂
2)AbstractFactory将产品对象的创建延迟到它的ConcreteFactory子类
5 效果
1)分离了具体的烊
2)易于交换产品系列
3)利于产品的一致性,一个应用一次只能使用同一个系列中的对象
4)难以扩展抽象工厂以生产新各类的产品(缺点)
6 UML
二、实例
场景:我们公司现在要开发一个新的产品,需要用到其它公司的零件来进行组装。开始的时候,我们和 A 公司合作, 使用他们生产的 ProcuctA1 和 ProductA2 产品。
所以,
// 生成我们的产品,需要用到 productA1 和 productA2void createOurProduct(){ ProductA1* pa1 = new ProductA1() ProductA2* pa2 = new ProductA2()}
可是,有一天,A公司突然提高了价格(世事多变!)。经过慎重考虑,我们打算换一家公司。调查后,发现 B 公司生产的 ProductB1, ProductB2 与A 公司生产的 ProductA1, ProductA2 是一样的,而且 B 公司的价格较为合理。然后,我们进行产品线调整。
// 生成我们的产品,需要用到 productB1 和 productB2 void createOurProduct(){ ProductB1* pb1 = new ProductB1() ProductB2* pb2 = new ProductB2() }
不过,我们发现虽然公司B的价格比较低,但是质量似乎不是那么好。所以,我们打算再换回使用公司A。于是,我们又得启用原来的方案。接着,我们不得不再换其它的公司。因为,我们得随时关注动态,选择对我们最好的方案。
那么,怎么可以让我们不用在每次做新的决策后,就要进行大动作,这样维护成本太高了。然后,我们想到了 abstract factory。我们生产的产品,不再依赖于产品,而是依赖于公司。我们只需要确定要和哪家公司合作,而不用具体关心每一个产品
// 这是接口,包含两个操作,生产 product1 和 product2 public abstract class Factory:{ public: virtual Product1 createProduct1(); virtual Product2 createProduct2();};// A 公司继承了 abstract factory,实现具体的生产public class FactoryA: public Factory{ public: Product1 createProduct1(); Product2 createProduct2();};// B 公司继承了 abstract factory,实现具体的生产。和A 公司生产同样的产品public class FactoryB: public Factory{ public: Product1 createProduct1(); Product2 createProduct2();};
// Product1 是一个抽象类,它具有一些属性public abstract class Product1:{ private: int size; int price; };// ProductA1 是由 公司 A 生产的poublic class ProductA1: public Product1{};// ProductB1 是由 公司 B 生产的poublic class ProductB1: public Product1{};
// Product2 是一个抽象类public abstract class Product2{ private: int size; int price; };//ProductA2 是由公司A生产的public class ProductA2: public Product2{ };//ProductB2 是由公司B生产的public class ProductB2: public Product2{ };
然后,我们可以很方便地随时更换我们的合作公司。
public createOurProduct(){ Factory* f = new FactoryA(); // 当我们想要使用 B 公司的产品时,只需要让我们合作的公司改为 B 即可,如下: // Factory* f = new FactoryB() // 至于具体的生产,我们就不用再担心了,下面这个部分不会发生改变 Product1 p1 = f -> createProduct1() Product2 p2 = f -> createProduct2()}