设计模式【一】:抽象工厂

设计模式【一】:抽象工厂

伪代码

//定义抽象工厂
class abstractFactory{
	createSet(){}
	createProductA(){};
	createProductB(){};
};

//定义调用者
productSet* makeProducts(abstractFactory& factory){
	set = factory->createSet();
	set.a = factory->createProductA();
	set.b = factory->createProductB();
	return set;
}

//实例化工厂类
class factoryForSituation1:public abstractFactory{
	createSet(){return set1}
	createProductA(){return a1};
	createProductB(){return b1};
};

/*
	现在想在某个情景(situation1)下生产一个productSet
*/
productSet1 = makeProducts(factoryForSituation1);

/*
	现在需要在另一个情景(situation2)下生产一个新的productSet。这个
	productSet里的a不变,但是b需要变为b2。于是我们实例化一个新的工厂类。
*/
class factoryForSituation2:public abstractFactory{
	createSet(){return set1}
	createProductA(){return a1};
	createProductB(){return b2};
};
/*
	生产一个 productSet2。可以看到,对于调用者(makeProducts)来说,调用的
	接口是不发生变化的。
*/
productSet2 = makeProducts(factoryForSituation2);

优缺点

优点
  • 隔离实体类
    工厂类继承了产品类的创建过程。对于调用者来说产品类的定义是不可见的。比如我只知道我要创建一个productSet的实例,但这个类的定义我无法修改。
  • 易于修改整族的产品类
    在一个情景下,抽象工厂一般只实例化一次,得到的工厂类生产适用于该情景的一整族产品。如果情景改变,重新实例化即可。这样整族的产品类被整体替换。调用者就不必对需要的产品类一一检查是否需要重新实现了——基于新的工厂类生产即可。
  • 加强整族产品的联系
    与上一点相似。使用抽象工厂可以确保得到的整族产品类适配于当前的情景。
缺点
  • 修改单个产品类较困难
    与优点伴生的就是修改单个产品类。由于工厂类是绑定一族的,因此想修改单个产品就需要对整个工厂类重新继承并实例化。A, B, C三个产品,我只要修改B,但我需要把A, B, C全部重新写一遍。

何时使用

  • 一个系统需要与其产品的生产、构成、表现方式独立。
  • 系统应配置有多个产品族之一。比如有三个族:(A, B, C)、(A, C, D)、(B, C, D),需要根据情境选择一个族。
  • 一族的多个产品需要一起使用,程序员为确保这种关系可以把这些产品放在同一个工厂类里。
  • 或者程序员只是对一个产品库提供一个统一接口。

实现时技巧

  • 实例化的工厂类最好是单例。一个情境下只实例化一次。
  • 生产产品时
    • 由于抽象工厂只提供接口,需要一个配套的生产方法,比如伪代码中的makeProducts()
    • 批量生产产品时可采取原型模式
  • 设计可扩展的工厂。比如给生产方法添加一个与情境关联的参数,这样在更改情境时就不必重新实例化一个工厂,只需在调用生产方法时更改参数;但这样会降低设计的安全性。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值