抽象工厂模式
引入问题
我们继续从上一篇工厂方法模式出发,客户的需求又有了改变,不仅需要制造IPhone手机,还需要为IPhone手机制造配对的手机壳。如果还是以工厂方法模式的做法,每个型号的手机壳创建一个工厂类,那客户在搭配的时候必须自己选择哪个手机配哪个手机壳。人为指定有关联的对象的依赖关系很容易出错,也不利于后期系统的维护。
解决方案
抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象。他与工厂方法模式的区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构。
抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象。
示例程序
首先,我们改进下上一篇中工厂方法模式的程序。
产品类
// 手机产品类
public abstract class IPhone {
public IPhone() {
}
}
public class IPhone4 extends IPhone {
public IPhone4() {
System.out.println("制造了iphone4...");
}
}
public class IPhone5 extends IPhone {
public IPhone5() {
System.out.println("制造了iphone5...");
}
}
// 手机壳产品类
public abstract class Shell {
public Shell() {
}
}
public class IPhone4Shell extends Shell {
public IPhone4Shell() {
System.out.println("制造了IPhone4的手机壳...");
}
}
public class IPhone5Shell extends Shell {
public IPhone5Shell() {
System.out.println("制造了IPhone5的手机壳...");
}
}
工厂类
public abstract class IPhoneSuitFactory {
public abstract IPhone createIPhone();
public abstract Shell createShell();
}
public class IPhone4SuitFactory extends IPhoneSuitFactory {
@Override
public IPhone createIPhone() {
return new IPhone4();
}
@Override
public Shell createShell() {
return new IPhone4Shell();
}
}
public class IPhone5SuitFactory extends IPhoneSuitFactory {
@Override
public IPhone createIPhone() {
return new IPhone5();
}
@Override
public Shell createShell() {
return new IPhone5Shell();
}
}
客户类
public class Customer {
public static void main(String[] args) {
IPhoneSuitFactory iPhone4SuitFactory = new IPhone4SuitFactory();
IPhoneSuitFactory iPhone5SuitFactory = new IPhone5SuitFactory();
iPhone4SuitFactory.createIPhone();
iPhone4SuitFactory.createShell();
iPhone5SuitFactory.createIPhone();
iPhone5SuitFactory.createShell();
}
}
输出结果
制造了iphone4... 制造了IPhone4的手机壳... 制造了iphone5... 制造了IPhone5的手机壳...
抽象工厂模式总结
优点:
1)抽象工厂拥有工厂方法模式的所有优点
2)除了工厂方法模式的优点,抽象工厂模式可以对一个产品等级内部的产品族的关联关系进行约束,而不需要人为或者引入新的类来进行管理。缺点:
产品族难以扩展,如果产品族中需要添加新的产品,那几乎所有的工厂类都需要修改,违背了开闭原则。