抽象工厂模式(Abstract Factory)
定义
Provide an interface for creating families of related or dependent objects without specifyingtheir concrete classes.
(为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类。)
说明
了解了简单工厂,工厂方法,似乎已经可以解决大部分问题了。其实事实也是如此,设计模式的出现主要目的是解耦,那么如何解耦,一个词“细化”。将业务尽可能的细化,细化是为了便于管理。只有将业务拆解成一个个琐碎的子业务,去应对业务变更的时候对局部的修改或添加才不致于影响大局。
抽象工厂模式正是对工厂方法的再一次补充,这种补充是建立在一定前提之下的。
从现实出发,想像一下这样的场景,假如你正在使用工厂方法模式,每一个工厂可以生产一种特定的产品,但是一个公司能够生产的产品一定是多种多样的。如果本公司要生产100种不同的产品,那根据工厂方法模式的定义公司要为每个产品各自建立一个工厂车间,那100个产品就是100个工厂车间,这很显然是不现实的。正是考虑到这种多产品的问题,设计模式提供了抽象工厂(Abstract Factory)。抽象工厂的作用正是在一定前提下,帮你分类这些工厂,比如按品牌分类,或者按照价格等级分类,这样会大大缩减系统中的工厂数量。
前面一直说抽象工厂是建立在一定的前提下,那么这个前提又是什么那?抽象工厂的目的是解决工厂方法中每个具体工厂只能生产一个产品的问题,那么就要考虑一个具体工厂能不能生产一类产品,当然是可以的。现在就涉及到产品分类问题,既然要分类就需要产品之间有共性,那么这个前提就是产品的共性。如果无法满足这个前提是无法使用抽象工厂模式的。
是否存在共性是能否使用抽象工厂模式的重要前提,这个共性至少要满足两个维度:
1、这个共性应该是设计到所关注的所有产品(区分产品族)
2、这个共性一定要有状态(设计不同的工厂)
假如某企业要生产两种酒一种牛栏山(56度,60度,65度),一种二锅头(56度,60度,65度),如果我们使用工厂方法模式每种酒都要建立一个单独的工厂,那么两种酒六种产品就要建立六个工厂。如果我们稍微分析一下就能发现这两种酒都包括56度,60度,65度这三类产品,从设计的角度来看可以有两种分配方法:
两种分配方案也就是两种创建工厂的方式,
1、以生产不同的度数为前提创建工程,那么就是三个具体工厂分别生成56度,60度,65度的白酒。
2、以生产不同的品牌为前提创建工厂,那么就是两个具体工厂分别生成牛栏山白酒和二锅头白酒。
这里还有一个问题,我们发现如果牛栏山可以生产80度白酒,而二锅头不可以生产时,那么抽象模式就无法应对了,这也是抽象模式的缺点,容易横向扩展,难以纵向扩展。
结构
包含的角色:
- AbstractFactory 一个抽象产品对象的操作接口
- ConcreteFactory 实现创建具体产品对象的工厂
- AbstractProduct 一类产品对象的抽象接口
- ConcreteProduct 需要生产的具体产品
- Client 调用者 仅使用AbstractFactory和AbstractProduct类声明的接口
类图1(工厂方法模式变体):
类图2(抽象工厂模式):
抽象工厂模式优势
- 分离了具体的类
因为工厂封装了创建产品对象的责任和过程,将客户与类的实现分离。客户通过它们的抽象操作实体类,产品的类名也在具体工厂实现中被分离,它们不会出现在客户代码中,体现了高内聚特点。
- 有利于产品一致性
当同一类产品对象被设计出来时,可以控制应用一次只使用统一类型的产品。
3.更容易应对变更
在一个系统中,一类工厂一般只需要实例化一次,当需要将某个产品变更到某一类产品族中,只需要修改具体产品族的生产工厂即可实现不同产品配置。
4.更易于修改一系列配置
比如在系统中,需要替换不同风格时,往往需要修改一系列配置,如果我们使用了抽象工厂模式,只需要将某一类型的具体工厂替换掉,就实现了这一系列sdsds配置的改变。
抽象工厂模式应用
在很多软件系统中需要更换界面主题,要求界面中的按钮、文本框、背景色等一起发生改变时,可以使用抽象工厂模式进行设计。
与工厂方法模式的区别
工厂方法模式 | 抽象工厂模式 |
---|---|
针对的是一个产品等级结构 | 针对多个产品等级结构所构成的产品族 |
只有一个抽象产品类,所有产品都实现了这个接口 | 拥有多个抽线产品类,根据不同的产品结构实现不同抽线类型 |
可以派生出多个具体产品 | 每一个抽象产品类都可以派生出相关的具体产品 |
一个抽象工厂类可以派生出多个具体工厂 | 一个抽象工厂类可以派生出多个具体工厂 |
每个具体工厂只能完成一种产品的生产 | 每个具体工厂可以完成多种产品的生产 |
当抽象工厂模式中每一个具体工厂类只创建一个产品对象,也就是只存在一个产品等级结构时,抽象工厂模式退化成工厂方法模式;当工厂方法模式中抽象工厂与具体工厂合并,提供一个统一的工厂来创建产品对象,并将创建对象的工厂方法设计为静态方法时,工厂方法模式退化成简单工厂模式。