以下内容重点介绍的设计模式中的抽象工厂模式,采用Java提供一个应用范例,分析其代码结构特性。结合具体案例分析引入抽象工厂模式后对系统架构和代码结构带来的好处,分析其中用到的多态机制,说明模块抽象封装的方法, 分析各个模块的内聚度和模块之间的耦合度。
1、什么是抽象工厂模式
工厂模式的本质是实例化对象时,用工厂方法代替new操作。将选择实现类、创建对象统一管理和控制。从而将调用者跟我们的实现类解耦。一般工厂模式分为三种,简单工厂模式,工厂方法模式,以及抽象工厂模式。简单工厂模式实例化对象的时候不再使用 new Object()形式,可以根据用户的选择条件来实例化相关的类。对于客户端来说,去除了具体的类的依赖。只需要给出具体实例的描述给工厂,工厂就会自动返回具体的实例对象。而工厂方法模式是对简单工厂模式进一步的解耦,因为在工厂方法模式中是一个子类对应一个工厂类,而这些工厂类都实现于一个抽象接口。这相当于是把原本会因为业务代码而庞大的简单工厂类,拆分成了一个个的工厂类,这样代码就不会都耦合在同一个类里了。前面介绍的工厂方法模式中考虑的是一类产品的生产,同种类称为同等级,也就是说:工厂方法模式只考虑生产同等级的产品,但是在现实生活中许多工厂是综合型的工厂,能生产多等级(种类) 的产品。简而言之,抽象工厂模式是用来生产不同产品族的全部产品。(对于增加新的产品,无能为力; 支持增加产品族),抽象工厂模式是工厂方法模式的升级版本,在有多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。
2、引入抽象工厂适用情况有哪些,有哪些常见的应用场景
一个系统要独立于它的产品的创建、组合和表示时。一个系统由多个产品系列中的一个来配置时。当你强调一系列相关产品对象的设计以便进行联合使用时。当你提供一个产品类库,而只想显示它们的接口而不是实现时。以上情况,均适用抽象工厂模式。当需要创建的对象是一系列相互关联或相互依赖的产品族时,便可以使用抽象工厂模式。说的更明白一点,就是一个继承体系中,如果存在着多个等级结构(即存在着多个抽象类),并且分属各个等级结构中的实现类之间存在着一定的关联或者约束,就可以使用抽象工厂模式。
抽象工厂模式在Java开发中应用十分广泛,比如JDK中Calendar的getInstance方法 ,JDBC中Connection对象的获取 ,Hibernate中SessionFactory创建,Session – spring中IOC容器创建管理bean对象,XML解析时的DocumentBuilderFactory创建解析器对象,反射中Class对象的newInstance()等。以下是抽象工厂模式结构图。
3、 案列分析
如图某工厂生产汽车,肯定要生产各种档次的汽车,本实例比较复杂,必须用抽象工厂模式来实现。
1) 为发动机,座椅,轮胎分别创建一个接口
2) 创建接口的实体类,以下为发动机代码
public interface Engine { public void run(); public void start(); } public class LuxuryEngine implements Engine { @Override public void run() { System.out.println("Run fast!"); } @Override public void start() { System.out.println("Start fast!"); } } public class LowEngine implements Engine{ @Override public void run() { System.out.println("Run slow!"); } @Override public void start() { System.out.println("Start slow!"); } }
3) 创建抽象工厂类
public interface CarFactory { public Engine createEngine(); public Seat createSeat(); public Tyre createTyre(); }
4) 创建具体工厂类,低档汽车工厂类与高档汽车工厂类
public class LuxuryCarFactory implements CarFactory { @Override public Engine createEngine() { return new LuxuryEngine(); } @Override public Seat createSeat() { return new LuxurySeat(); } @Override public Tyre createTyre() { return new LuxuryTyre(); } } public class LowCarFactory implements CarFactory{ @Override public Engine createEngine() { return new LowEngine(); } @Override public Seat createSeat() { return new LowSeat(); } @Override public Tyre createTyre() { return new LowTyre(); } }
5)该项目UML类图
6)
由该案列可以看出,分离了具体的类。客户通过抽象接口操纵实例,产品的类名也在具体工厂的实现中被分离,它们不出现在客户代码中。易于交换产品系列。一个具体工厂类只在初始化时出现一次,这使得改变一个应用的具体工厂变得很容易,只需改变具体的工厂即可使用不同的产品配置。有利于产品的一致性。当一个系列的产品对象被设计成一起工作时,一个应用一次只能使用同一个系列中的对象,这一点很重要,而抽象工厂很容易实现这一点。
该架构很好的应用了java 的多态机制,如工厂生产汽车时,CarFactory根据具体工厂的不同生产不同档次的汽车。Engine类指向不同档次的发动机。很明显整个项目的内聚程度很高,耦合程度很低。可以较大程度上解耦,客户类和产品实现类隔离开,只依赖产品接口(抽象产品),产品实现类如何改动与客户类完全无关。