Java设计模式(6)-抽象工厂模式

如果工厂模式中需要生产多种类型的产品,那么工厂方法模式就适合了,需要用到抽象工厂模式。 1. 简介 抽象工厂模式,定义抽象工厂,并将产品生产延迟到具体工厂实现中,而它生产的产品都是同种类型的。比如,电视机工厂生产的都是电视机,电视机是一个抽象产品,而它的具体实现有黑白电视、彩色电视、液晶电视等等,但是都属于同一种产品类型-电视机。 如果现在电视机工厂不仅生产电视,还能生产空调等其他电器了,那么,我们称电视机、空调等不同类型的产品为产品簇,代表不同类型的多种产品。 Figure 1. 产品簇示意图 现在,工厂方法模式不适用了,我们需要使用抽象工厂模式。 抽象工厂模式(Abstract Factory Pattern)的定义如下:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类,访问类无须指定具体的类就可以得到同组的不同类型的产品。 抽象工厂模式升级了工厂方法模式,将原本仅能创建同种类型的产品升级为可以创建多种类型的产品. 优点 可以使用工厂模式生产多个产品簇,新增同类型产品时只需要新增一个具体工厂实现,不需要修改客户端代码,遵循开闭原则。 缺点 当产品簇中需要新增产品时,会修改原产品簇的所有工厂类,不符合开闭原则。 因此,抽象工厂模式在使用时应该酌情考虑其倾斜性,新增同类产品时,遵循开闭原则;但是,产品簇添加新的产品,所有的工厂类都需要添加生产新产品的方法。 2. 适用场景 抽象工厂模式通常适用于以下场景: 当需要创建的对象是一系列相互关联或相互依赖的产品族时,如电器工厂中的电视机、电风扇、洗衣机、空调等 系统中有多个产品族,但每次只使用其中的某一族产品,比如有人只喜欢穿某一个品牌的衣服和鞋 系统中提供了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构 3. 结构 抽象工厂模式的结构与工厂方法模式一样,同样具有抽象工厂、抽象产品、具体工厂、具体产品四大角色: 抽象工厂: 定义产品创建的接口,具有多个产品创建方法,这些方法负责创建不同的产品; 具体工厂: 实现抽象工厂的产品创建方法,用于具体实现如何创建这些产品簇中不同的产品; 抽象产品: 定义产品的规范,如产品规格、属性、功能等;就有多个抽象产品,组成产品簇; 具体产品: 抽象产品的具体实现,具体产品与具体工厂是多对一的关系,即一个具体工厂可以生产多个具体产品。 Figure 2. 抽象工厂模式结构 可以看到,AbstractFactory 是顶层抽象工厂接口,定义了创建不同产品簇的方法。不同的产品簇抽象出不同的产品接口,如图中的 Product1、Product2。 如果要添加一个产品的具体实现,那么客户端和工厂不需要改动,只需要新增一个具体工厂即可,那么结构变成了这样: Figure 3. 新增具体产品时的类结构变化 图中紫色部分是需要新加的部分,原工厂和客户端不需要做改动,遵循开闭原则。 但是,如果现在要增加新的产品线,即是说产品簇中要新加一个新产品,那么原工厂代码需要添加生产这个新产品的方法,而且客户能也需要为调用这个新方法而做出修改,此时的类结构如下图: Figure 4. 产品簇中添加新产品时的类结构变化 图中紫色部分为新加的产品,而原来的工厂添加新的方法(红色部分)来生产这个新的 Product3 产品,客户端也需要修改代码来调用工厂的新方法。 4. 与工厂方法模式的比较 抽象工厂模式与工厂方法模式在结构上其实是相同的,但是他们创建的产品类型不同: 工厂方法模式仅能创建某一类产品,而抽象工厂模式可以创建多种类型的产品; 工厂方法模式如果能够支持创建多种类型的产品,那么它会演变为抽象工厂模式;同理,如果抽象工厂模式仅创建同一类型的产品,它就变成了工厂方法模式 抽象工厂模式具有工厂方法模式的优点和缺点 5. 示例 接下来看一个实例。现在有一个电器工厂,可以生产电视机、空调,假设电视机有黑白、彩色两种,空调有挂式和柜式空调两种。工厂既能生产电视机,也能生产空调。我们用抽象工厂来设计,创建两个具体的工厂,工厂A来生产黑白电视机和挂式空调,而工厂B来生产彩电和柜式空调。类的结构如下: Figure 5. 电器工厂设计类图...

2020-06-09 · 3 min · 612 words · Hank