简介
在了解抽象工厂模式之前,我们必须先了解一个概念产品族。所谓的产品族:是指位于不同产品等级结构中,功能相关联的产品组成的家族。
举个例子:在肥宅心中除了快乐水最喜欢的就是动漫了。
在上面的图中,热血番和搞笑番称为两个不同的等级结构;而国产动漫和日本动漫则称为两个不同的产品族。具体点就是。国漫的热血番和日漫的热血番属于同一等级结构,国漫的搞笑番和日漫的搞笑番属于同一等级结构;国漫热血番和国漫搞笑番属于同一产品族,日漫热血番和日漫搞笑番属于同一产品族。明白了等级结构和产品族的概念,我们来看抽象工厂的定义:抽象工厂模式(Abstract Factory Pattern)是为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
实例
就以动漫为例子:
产品接口定义:
// 热血番剧public interface BloodDrama { String name();}// 搞笑番剧public interface FunnyDrama { String name();}复制代码
产品具体实现:
// 中国热血番public class ChinaBloodDrama implements BloodDrama { @Override public String name() { return "中国热血番"; }}// 中国搞笑番public class ChinaFunnyDrama implements FunnyDrama { @Override public String name() { return "中国搞笑番"; }}//日本热血番public class JapanBloodDrama implements BloodDrama { @Override public String name() { return "日本热血番"; }}//日本搞笑番public class JapanFunnyDrama implements FunnyDrama { @Override public String name() { return "日本搞笑番"; }}复制代码
工厂接口定义:
public interface Factory { BloodDrama createBloodDrama(); FunnyDrama createFunnyDrama();}复制代码
工厂具体实现:
// 国漫工厂public class ChinaAnimeFactory implements Factory { @Override public BloodDrama createBloodDrama() { return new ChinaBloodDrama(); } @Override public FunnyDrama createFunnyDrama() { return new ChinaFunnyDrama(); }}// 日漫工厂public class JapanAnimeFactory implements Factory { @Override public BloodDrama createBloodDrama() { return new JapanBloodDrama(); } @Override public FunnyDrama createFunnyDrama() { return new JapanFunnyDrama(); }}复制代码
客户端(肥宅):
public class Fz { @Test public void watch() { // 国漫工厂 Factory chinaAnimeFactory = new ChinaAnimeFactory(); System.out.println("肥宅观看:" + chinaAnimeFactory.createBloodDrama().name()); System.out.println("肥宅观看:" + chinaAnimeFactory.createFunnyDrama().name()); // 日漫工厂 Factory japanAnimeFactory = new JapanAnimeFactory(); System.out.println("肥宅观看:" + japanAnimeFactory.createBloodDrama().name()); System.out.println("肥宅观看:" + japanAnimeFactory.createFunnyDrama().name()); }}复制代码
类图
优点
-
具有工厂方法模式的优点外;
-
在类内部对产品族的关联关系进行定义和描述,而不必专门引入一个新的类来进行管理;
-
当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
缺点
产品族 的扩展将是一件十分费力的事情,假如产品族中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改。例如上面例子扩展一个 治愈番。所以使用抽象工厂模式时,对产品等级结构的划分是非常重要的。
适用场景
当需要创建的对象是一系列相互关联或相互依赖的产品族时,便可以使用抽象工厂模式。例如 系统日志记录:可能存储到数据库、本地文件、缓存、远程服务器等,用户可以自己选择记录方式。
总结
无论是简单工厂模式,工厂方法模式,还是抽象工厂模式,他们都属于工厂模式,在形式和特点上也是极为相似的,他们的最终目的都是为了解耦。在使用时,我们不必去在意这个模式到底工厂方法模式还是抽象工厂模式,因为他们之间的演变常常是令人琢磨不透的。经常你会发现,明明使用的工厂方法模式,当新需求来临,稍加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了;而对于抽象工厂模式,当减少一个方法使的提供的产品不再构成产品族之后,它就演变成了工厂方法模式。所以,在使用工厂模式时,只需要关心降低耦合度的目的是否达到了。