上一篇文章介绍的工厂方法模式中考虑的是一类产品的生产,如畜牧场只养动物、电视机厂只生产电视机、计算机软件学院只培养计算机软件专业的学生等。
同种类称为同等级,也就是说:工厂方法模式只考虑生产同等级的产品,但是在现实生活中许多工厂是综合型的工厂,能生产多等级(种类) 的产品,如农场里既养动物又种植物,电器厂既生产电视机又生产洗衣机或空调,大学既有软件专业又有生物专业等。
本节要介绍的抽象工厂模式将考虑多等级产品的生产,将同一个具体工厂所生产的位于不同等级的一组产品称为一个产品族;
作用
- 最大的好处便是易于交换产品系列,由于具体工厂类,在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同产品配置。
- 它让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操作实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。
首先创建三个接口:
//空调
public interface AirConditioner {
void airConditionerInfo();
}
//风扇
public interface Fan {
void fanInfo();
}
//冰箱
public interface Fridge {
void fridgeInfo();
}
创建具体的产品:美的冰箱、美的风扇、美的空调。
public class MediaAirConditioner implements AirConditioner {
@Override
public void airConditionerInfo() {
System.out.println("美的空调");
}
}
public class MediaFan implements Fan {
@Override
public void fanInfo() {
System.out.println("美的风扇");
}
}
public class MediaFridge implements Fridge{
@Override
public void fridgeInfo() {
System.out.println("美的冰箱");
}
}
它们都是同一个产品族的,都是美的旗下的产品。
抽象工厂:
public interface Factory {
Fridge createFridge();
AirConditioner createAirConditioner();
Fan createFan();
}
美的工厂:
public class MediaFactory implements Factory{
@Override
public Fridge createFridge() {
// TODO Auto-generated method stub
return new MediaFridge();
}
@Override
public AirConditioner createAirConditioner() {
// TODO Auto-generated method stub
return new MediaAirConditioner();
}
@Override
public Fan createFan() {
// TODO Auto-generated method stub
return new MediaFan();
}
}
可以看到,在这个工厂里面生产的所有产品对象都不是同一个产品等级的,它们属于同一个产品族,该工厂生产的一系列对象都是相关的。
就像定义说的:抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口。如果现在我们希望生产海尔的一系列产品就可以扩展抽象产品接口创建一系列海尔产品类,创建海尔的工厂负责生产海尔的产品。
想生产格力的只需要进行扩展对应的产品和工厂就好了,从这点看完全遵循开闭原则。不过抽象工厂模式的不足也很明显,如果美的现在又搞洗衣机了,就需要修改接口和所有的实现类,因此对于扩展一个新的产品等级来说,不遵循开闭原则。
测试:
public class Test {
public static void main(String[] args) {
Factory factory=new HaierFactory();
AirConditioner airConditioner=factory.createAirConditioner();
Fan fan=factory.createFan();
Fridge fridge=factory.createFridge();
airConditioner.airConditionerInfo();
fan.fanInfo();
fridge.fridgeInfo();
}
}
优缺点
优点:
1、易于交换产品系列,由于具体工厂类,在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。
2、它让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。
缺点:
如果美的现在又搞洗衣机了,就需要修改接口和所有的实现类,因此对于扩展一个新的产品等级来说,不遵循开闭原则。
- 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口
- 增加了系统的抽象性和理解难度