创建型设计模式概述
- 抽象了实例化过程,能使系统更好的创建、组合、表示对象
- 类创建模式使用继承改变被实例化的类;对象创建模式将实例化委托给另一个对象
对象创建型模式--抽象工厂(Abstract Factory)
动机:多个页面布局的应用程序。不同风格的窗口、按钮、滚动条等
结构
组成部分
- AbstractFactory:声明一个创建抽象产品对象的操作接口
- ConcreteFactory:实现创建具体产品对象的操作
- AbstractProduct:为一类产品对象声明一个接口
- Product:定义一个将被相应的具体工厂创建的产品对象。实现AbstractProduct
- Client:仅适用由AbstractFactory和AbstractProduct类声明的接口
-
public class ZhuSHi {//A类产品 public void setName(String name) { System.out.println("主食是"+ name); } } public class HuoGuo {//A类产品 public void setName(String name) { System.out.println("火锅口味"+name); } } //美食工厂 public abstract class MeiShiFactory{//抽象工厂 public abstract ZhuSHi getZhuShi();//A类产品 public abstract HuoGuo getHuoGuo();//B类产品 } public class ChongQingMeshi extend MeiShiFactory {//工厂1 public ZhuSHi getZhuShi(){//正常编程场景中返回产品 return new ZhuSHi("面条"); } public HuoGuo getHuoGuo(){ return new HuoGuo("酸菜火锅"); } } public class DongBeiMeshi extend MeiShiFactory {//工厂1 public void getZhuShi(){ return new ZhuSHi("米饭"); } public void getHuoGuo(){ return new HuoGuo("爆辣火锅"); } } public class Client { public static void main(String[] args) { MeiShiFactory factory; if(args[0] == 0) { factory = new ChongQingMeshi(); }else { factory = new DongBeiMeshi(); } ZhuSHi zhuShi = factory.getZhuShi(); HuoGuo zhuShi = factory.getHuoGuo(); } }
协作
- 通常在运行时刻创建一个ConcreteFactory类的实例。这一具体的工厂创建具有特定实现的产品对象。为创建不同的产品对象,客户应适用不同的具体工厂
- AbstractFactory将产品对象的创建延迟到它的ConcreteFactory子类
效果-优缺点
- 分离了具体的类:Abstract Factory模式帮助控制一个应用创建的对象的类。因为一个工厂封装创建产品对象的责任和过程,它将客户与类的实现分离。客户通过他们的抽象接口操作实例。产品的类名也在具体工厂的实现中被分离;他们不出现在客户代码中。
- 易于交换产品系列:一个具体工厂类在一个应用中仅出现一次--即在它初始化的时候,这使得改变一个应用的具体工厂变得很容易。它只需要改变具体的工厂即可使用不同的产品配置,这是因为一个抽象工厂创建了一个完整的产品系列,所以整个产品系列会立刻改变。
- 有利于产品的一致性:当一个系列的产品对象被设计成一起工作时,一个应用智能使用同一系列中的对象。
- 难以支持新种类的产品,难以扩展抽象工厂以生产新种类的产品。因为AbstractFactory接口确定了可以被创建的产品集合。支持新种类的产品就需要扩展该工厂接口,这将涉及AbstractFactory类及其所有子类的改变。
实现建议
- 将工厂作为单件:一个应用中一般每个产品系列只需一个ConcreteFactory的实例,因此工厂通常最好实现为单例
- 创建产品:AbstractFactory仅声明一个创建产品的接口,真正创建产品是由ConcreteProduct子类实现的。最通常的一个办法是为每一个产品定义一个工厂方法。一个具体的工厂将为每个产品重定义该工厂方法以指定产品。虽然这样实现简单,但却要求每个产品系列都要有一个新的具体工厂子类,即使这些产品系列的差距很小
- 定义可扩展的工厂:一个更灵活但不安全的设计是给创建对象的操作增加一个参数(整数、类标识符、字符串等),该参数指定额将被创建的对象的种类,这也是上述缺点的解决方案。我不太清楚的是为什么不安全
意图:提供一个创建一系列相关活相互依赖对象的接口,而无需制定他们具体的类
别名:Kit
适用性:
- 一个系统要独立于它的产品的创建、组合和表示时;
- 一个系统要由多个产品系列中的一个来配置时
- 当你要强调一系列相关的产品对象的设计以便进行联合使用时
- 当你提供一个产品类库,而只想他们的接口而不是实现时
相关模式:
AbstractFactory类通常使用工厂方法(Factory Method)实现,也可以用Prototype实现
一个具体的工厂通常是一个单例(Singleton)
文章摘抄于:《设计模式:可复用面向对象软件的基础》
总结:
想象一个可以现场给你做产品的大型超市,你的需求其实只是产品,而不关心产品的实现,比如你说:你要一塑料瓶装500ml的无糖的可乐,那么后台工厂就开始组装,一个500ml的塑料瓶,一个符合规格的商标 ,一个符合规格的盖子,一定量的无糖的可口可乐,合体--产品生成。
- 消费者不关心产品产出过程,只需要这个产品
- 消费者只能要一瓶,如果要两瓶要请求两次,或者改造工厂,让支持数量
- 产品的流程应该大致类似,比如下一个顾客想要一个番茄炒蛋,这个工厂就不再合适
- 产品是由多个产品部件构成的,只有一个部件就没必要这么折腾