进一步优化工厂方法模式,将之泛化,以适应更加复杂的业务结构。
抽象工厂模式
抽象工厂模式是工厂方法模式的泛化版,在工厂方法模式中,每个具体的工厂类只能生产一种具体产品,而在抽象工厂方法模式中,每个具体的工厂可以生产多个具体产品。
引入两个概念
- 产品等级结构:即产品的继承结构,如一个抽象类是手机,其子类有iPhone、Huawei等,则抽象手机与具体品牌的手机之间构成了一个产品等级结构。
- 产品族:在抽象工厂模式中,产品族是指同一个工厂生产的,位于不同产品等级结构中的一组产品,如Apple公司生产的iPhone、iPad,iPhone位于手机产品等级结构中,iPad位于平板电脑产品等级结构中。
角色
Abstract Factory(抽象工厂)
抽象工厂用于声明生产抽象产品的方法,在一个抽象工厂中可以定义一组方法,每个方法对应一个产品等级结构。
Concrete Factory(具体工厂)
具体工厂实现了抽象工厂声明的生成抽象产品的方法,生成一组具体产品,这些产品构成了一个产品族,每个产品都位于某个产品等级结构中。
Abstract Product(抽象产品)
抽象产品为每种产品声明接口,在抽象产品中定义了产品的抽象业务方法。
Concrete Product (具体产品)
具体产品定义具体工厂生产的具体产品对象,实现抽象产品接口中定义的业务方法。
类图
实例
定义抽象产品手机
1 2 3
| public interface Phone { public void powerOn(); }
|
定义该产品等级结构中的具体产品
1 2 3 4 5 6
| public class iPhone implements Phone { @Override public void powerOn() { System.out.println("The iPhone is powered on."); } }
|
1 2 3 4 5 6
| public class HuaweiPhone implements Phone { @Override public void powerOn() { System.out.println("The Huawei phone is powered on."); } }
|
定义抽象产品平板电脑
1 2 3
| public interface Pad { public void powerOn(); }
|
定义该产品等级结构中的具体产品
1 2 3 4 5 6
| public class iPad implements Pad { @Override public void powerOn() { System.out.println("The iPad is powered on."); } }
|
1 2 3 4 5 6
| public class HuaweiPad implements Pad { @Override public void powerOn() { System.out.println("The Huawei pad is powered on."); } }
|
定义抽象工厂类,其中声明了生产两个抽象产品的方法
1 2 3 4 5
| public interface DeviceFactory { public Phone producePhone();
public Pad producePad(); }
|
定义两个具体工厂,每个具体工厂都实现了抽象工厂中声明的生产抽象产品的方法
1 2 3 4 5 6 7 8 9 10 11
| public class Apple implements DeviceFactory { @Override public Phone producePhone() { return new iPhone(); }
@Override public Pad producePad() { return new iPad(); } }
|
1 2 3 4 5 6 7 8 9 10 11
| public class Huawei implements DeviceFactory { @Override public Phone producePhone() { return new HuaweiPhone(); }
@Override public Pad producePad() { return new HuaweiPad(); } }
|
客户端测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class Client { public static void main(String[] args) { DeviceFactory deviceFactory = new Apple(); Phone phone = deviceFactory.producePhone(); phone.powerOn(); Pad pad = deviceFactory.producePad(); pad.powerOn();
deviceFactory = new Huawei(); Phone phone1 = deviceFactory.producePhone(); phone1.powerOn(); Pad pad1 = deviceFactory.producePad(); pad1.powerOn(); } }
|
运行结果为
1 2 3 4
| The iPhone is powered on. The iPad is powered on. The Huawei phone is powered on. The Huawei pad is powered on.
|
模式优缺点
优点
- 抽象工厂模式隔离了具体类的生产,使得客户端不需要知道什么被创建,由于这种隔离,更换一个具体工厂就变得相对容易,所有的具体工程都实现了抽象工厂中定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为;
- 当一个产品族中的对各对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。这对一些需要根据当前环境来决定其行为的软件系统来说非常实用;
- 增加新的具体工厂和产品族很方便,无需修改已有系统,符合开闭原则。
缺点
- 在添加新的产品对象时,难以扩展抽象工厂来生产新种类的产品,这是因为在抽象工厂角色中规定了所有可能被创建的产品集合,要支持新种类的产品就意味着要对该接口进行扩展,而这将涉及对抽象工厂角色及其所有子类的修改。