设计模式随笔(三):抽象工厂(Abstract Factory)

来源:互联网 发布:中指院数据库 编辑:程序博客网 时间:2024/05/10 12:54

抽象工厂(Abstract Factory

 

作者:Will LeeQQ31940767EMailw.lee@live.cn

声明:本文可用于个人学习、参考,未经本人授权严禁用于商业用途。有朋友转载或引用本文请注明作者和出处,谢谢!!

 

1          模式简介

Factory Method有别,Abstract Factory用于创建一系列产品对象。

这里的“一系列”,可以简单理解为多种类型,每种类型的对象都具有相同的接口,在面向对象设计中,它们具有共同的superclass打个比方:帽子,上衣,裤子,是不同类型的产品,所有的帽子都能戴在头上(帽子的共性,-__-……),现在有一个服装厂,专门生产帽子、上衣和裤子,像帽子,它们又能生产儿童帽和成年帽……ok,这家服装厂能生产“一系列”的产品,这家服装厂就是Abstract Factory模式中的Factory角色。

 

Abstract Factory使用了Factory Method,所以它也具有“将具体对象创建操作从父类延缓到子类”的功效,同时,前者又扩展了后者,Abstract Factory往往包含多个Factory Method,所以Abstract Factory又能创建多种不同类型的对象。

 

2          模式结构

Abstract Factory模式结构如图1所示:

 

1 Abstract Factory模式结构

 

看上去错综复杂,实际上设计层次很清晰:分两层,抽象层和实现层,从类的继承结构上,也不难看出本模式所涉及的两大角色:

1.         Product产品:有多种类型的产品,每种类型产品都从一个公共的superclass继承。Client通过AbstractProduct接口使用具体产品功能;

2.         Factory工厂:AbstractFactory声明一系列接口,每个接口相当于一种类型产品的Factory Method(参见我关于该模式的另一篇论述),比如CreateProductAAbstractProductA类型产品的Factory MethodConcreteFactory负责实现AbstractFactory声明的这些工厂方法,可能会有多种ConcreteFactory子类型,每种ConcreteFactory生产风格、特性一致的产品(比如儿童服装厂专门生产儿童帽子、儿童上衣、儿童裤)。

 

Client客户程序统一面向AbstractFactoryAbstractProduct,这样Client不依赖于具体实现,就容易做到对扩展开放、多更改封闭,同时该模式也是DIP的体现。

 

3          核心思想

Factory Method有些类似:

抽象工厂创建抽象产品,具体工厂创建具体产品(两个类层次,两种类继承结构);

抽象工厂支持创建多种类型的抽象产品,具体工厂支持创建多种类型的具体产品(FactoryProduct:一对多);

客户统一面向抽象类层次(AbstractFactoryAbstractProduct),不依赖于具体实现层次(ConcreteFactoryConcreteProduct);

 

Abstract Factory模式使Client和具体产品类(含其创建操作)分离,使上层设计得以稳定,Client仅需针对接口编程,而无需针对实现编程;整个设计易于增加新的产品系列,比如在已有儿童系列服装产品的基础上,想增加成年系列服装产品,仅需要从AbstractFactory继承,增加一个成年服装厂即可,对原有儿童服装厂、产品以及客户没有影响。

 

Abstract Factory模式设计的程序难以增加新种类产品:整个工厂继承结构都需要修改。

 

4          实现关键点

1.         ConcreteFactory实现方式

每种类型的产品,通常只需要一个ConcreteFactory实例,所以,ConcreteFactory一般实现为Singletoon模式比较好。

 

2.         难以增加新的产品

前面说了,如果要增加一种新产品,需要在AbstractFactory中增加一个新的工厂方法,这和Factory Method模式中增加一种新产品就要增加一个Creator创建类道理是一样的。继而,所有的ConcreteFactory均需要修改,去实现该方法。

这在不断新增产品类型的场景下,几乎是不可容忍的!

 

Factory Method一样,我们可以给工厂方法增加一个参数,用以指明产品类型,从而让一个工厂方法可以创建多种类型产品对象,这样或许可以减少新产品扩展带给我们的痛苦。但这种方法的副作用也很大:所有类型的产品必须拥有公共的superclass,不然让工厂方法返回什么类型呢?这在有些场景下很难,甚至行不通,因为如果Client想使用特定产品的操作,就需要进行向下类型转换,这是比较危险的。

 

很多时候,设计,就是在不同选择之间的权衡,设计,就是不断的面对一个又一个的十字路口!

 

5          相关设计模式

Abstract Factory模式使用并扩展了Factory Method模式;

实际上,如果采用给工厂方法增加参数的设计,那么Abstract Factory模式就等同于Factory Method

Abstract Factory模式中的ConcreteFactory一般实现为Singleton模式;

 

6          设计样例

就以服装厂的比方为例。

有帽子、上衣、裤子三种产品,每种产品又分儿童、成年两类,使用Abstract Factory模式设计如图2所示。

 

2 服装厂设计类图

 

主要是程序类框架的设计,具体属性、操作,这里不必过于关注,可根据实际需要增加或删除。代码样例,限于篇幅,此处略。