产品族创建–抽象工厂模式
工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问题。
但由于工厂方法模式中的每个工厂只生产一类产品,可能会导致系统中存在大量的工厂类,势必会增加系统的开销。此时,可以考虑将一些相关的产品组成一个“产品族”,由同一个工厂来统一生产,这就是本章将要学习的抽象工厂模式的基本思想。
在工厂方法模式中,具体工厂负责生产具体的产品,每个具体工厂对应一种具体产品,工厂方法具有唯一性。一般情况下,一个具体工厂中只有一个或者一组重载的工厂方法。但是,有时希望一个工厂可以提供多个产品对象,而不是单一的产品对象。
例如一个电器工厂,它可以生产电视机、电冰箱、空调等多种电器,而不是只生产某一种电器。为了更好地理解抽象工厂模式,这里先引入如下两个概念:
- 产品等级结构。产品等级结构即产品的继承结构,例如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。
- 产品族。在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品。例如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中,海尔电视机、海尔电冰箱构成了一个产品族。
产品等级结构与产品族示意图如图所示。
在图中,一共包含3个产品族,分属于3个不同的产品等级结构。只要指明一个产品所处的产品族以及它所属的等级结构,就可以唯一确定这个产品。
当系统所提供的工厂生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构、属于不同类型的具体产品时,就可以使用抽象工厂模式。
抽象工厂模式是所有形式的工厂模式中最为抽象和最具一般性的一种形式。抽象工厂模式与工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建。当一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象时,抽象工厂模式比工厂方法模式更为简单、更有效率。
抽象工厂模式示意图如图所示。
在图中,每一个具体工厂可以生产属于一个产品族的所有产品,例如海尔工厂生产海尔电视机、海尔冰箱和海尔空调,所生产的产品又位于不同的产品等级结构中。如果使用工厂方法模式,实现图所示结构需要提供9个具体工厂,而使用抽象工厂模式只需要提供3个具体工厂,极大地减少了系统中类的个数。
抽象工厂模式的实现
- 产品接口和具体实现类
// 电视机接口和具体实现类
public interface TV {
void display();
}
public class HaierTV implements TV {
@Override
public void display() {
System.out.println("Displaying Haier TV");
}
}
public class SonyTV implements TV {
@Override
public void display() {
System.out.println("Displaying Sony TV");
}
}
public class SamsungTV implements TV {
@Override
public void display() {
System.out.println("Displaying Samsung TV");
}
}
// 冰箱接口和具体实现类
public interface Refrigerator {
void cool();
}
public class HaierRefrigerator implements Refrigerator {
@Override
public void cool() {
System.out.println("Cooling with Haier Refrigerator");
}
}
public class SonyRefrigerator implements Refrigerator {
@Override
public void cool() {
System.out.println("Cooling with Sony Refrigerator");
}
}
public class SamsungRefrigerator implements Refrigerator {
@Override
public void cool() {
System.out.println("Cooling with Samsung Refrigerator");
}
}
// 空调接口和具体实现类
public interface AirConditioner {
void heat();
}
public class HaierAirConditioner implements AirConditioner {
@Override
public void heat() {
System.out.println("Heating with Haier Air Conditioner");
}
}
public class SonyAirConditioner implements AirConditioner {
@Override
public void heat() {
System.out.println("Heating with Sony Air Conditioner");
}
}
public c