程序员的知识教程库

网站首页 > 教程分享 正文

白话设计模式之抽象工厂模式(抽象工厂模式是简单工厂模式的升级版本)

henian88 2024-10-18 05:58:32 教程分享 2 ℃ 0 评论

抽象工厂模式

抽象工厂模式(Abstract Factory Pattern)

提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,它是一种对象创建型模式。为创建一组对象提供了解决方案,与工厂方法模式相比,它不在是一个工厂创建一种产品,而是一个工厂创建多个产品(产品簇)。

案例

某西服服装制作厂生产的西服分为春季和夏季两种不同的款式,我们都知道西服是套装,由上衣和裤子组成,在销售的时候只能成套销售,但是在穿的时候又可以分开来穿。上衣、裤子就是单一的产品角色,西服是上衣和裤子的一个统称,那么西服就是一个产品簇角色。根据此信息我们设计一个制作春季和夏季西服的系统,客户端只需要知道自己需要春季还是夏季西服,我们就能为其提供对应季节的西服(上衣+裤子)。具体设计类图如下所示:

西服制造工厂结构类图

类图解析

  • ClothesFactory(抽象工厂)。它申明了多个用于创建不同产品的方法。makeCoat()创建上衣;makePants()创建裤子。

  • SummerFactory(生产夏季西服)、SpringFactory(生产春季西服),他们两个为具体的抽象工厂实现类,也就是具体的工厂,都实现了父类接口的方法。

  • Coat(上衣)、Pants(裤子),他们两个为抽象产品类,为每种产品申明了具体业务的接口方法。注意:我这里因为上衣和裤子都是通过制作得来的,所以两个接口的方法名称相同,在真实业务场景下每种产品都有各自的具体业务实现方法,望读者别误解。

  • SummerCoat、SummerPants、SpringCoat、SpringPants,他们都是具体的产品实现类,SummerCoat用于制作夏季上衣,SummerPants用于制作夏季裤子,SpringCoat用于制作春季上衣,SpringPants用于制作春季裤子。

客户端测试

客户端测试调用代码片段如下图所示,这里只做了生产春季西服的测试调用。我们可以对客户端调用进行优化,将创建具体工厂实例这个步骤用反射的方式完成。创建一个XML文件用于保存具体的工厂实现类的类名称,通过读取该XML文件的对应节点下的类名称,然后使用反射机制实例化具体的工厂实现类,具体如何实现这里就不做详细说明了,有兴趣的朋友可以自己完善一下客户端调用,使用反射机制完成具体工厂类的实例化。

测试客户端调用

如果需要增加其他季节的西服制作需要怎么做呢?答案很简单,只需要创建一个对应季节的具体工厂实现类,并实现ClothesFactory接口,然后在创建对应季节的Coat和Pants具体实现类即可。从这里可以看出抽象工厂模式完全符合开放闭合原则。

总结

抽象工厂模式是工厂方法模式的进一步升级,一个工厂生产一个产品簇的具体产品,当然工厂方法模式也能完成这样的设计,但是会增加工厂类的个数,这样不利于系统的理解和维护。由于它提供了功能更为强大的工厂类并且具备较好的可扩展性,在软件开发中得以广泛应用,尤其是在一些框架和API类库的设计中,例如在Java语言的AWT( 抽象窗口工具包) 中就使用了抽象工厂模式,它使用抽象工厂模式来实现在不同的操作系统中应用程序呈现与所在操作系统一致的外观界面。抽象工厂模式增加新的产品簇非常方便,同时也满足了开放闭合原则。

抽象工厂模式的主要缺点如下:

增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便,违背了“开闭原则”。如上案例,如果需要增加一件衬衣作为西服整体的一部分,也就是衬衣新增到西服的产品簇中,那么ClothesFactory接口及对应的已经实现的类需要进行修改。

今天就先写到这里,如有问题,欢迎吐槽。在此特别感谢design-pattern-java一书的作者,是他让我开始对设计模式产生了感觉。地球不爆炸,我们不放假,good good study day day up !!

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表