?前面我们了解到工厂方法模式通过引入抽象工厂的概念,使得产品对象的创建可以依赖于具体工厂,但是这种设计模式最大的问题是会造成类的数量爆炸式增长。对于这个问题,抽象工厂模式通过引入两个新的概念:产品等级与产品簇,来解决工厂方法的工厂类过多的问题。
?在正式进入抽象工厂模式学习之前,我们先来了解一下这两个概念:
?抽象工厂模式:为创建一组对象提供了一种解决方案,与工厂方法模式相比,抽象工厂模式中的工厂角色不只创建一种产品,而是负责一个产品簇对象的生产。抽象工厂模式是一种创建型的设计模式。
?在抽象工厂模式中,包含4个角色:
?抽象工厂模式是一类比较复杂的对象创建型模式,复杂的地方在于产品簇和产品等级维度的划分,有时候业务界限比较模糊,这些都高度依赖于开发人员的业务素养和代码积累等。
?接下来我们就以刚才海尔、美的工厂生产冰箱和电视机的产品为例子,写一个demo:
public interface AbstractFactory {
// 创建电视的方法
TelevisionProduct createTelevisionProduct();
// 创建冰箱的方法
RefrigeratorProduct createRefrigeratorProduct();
}
/**
* 美的生产工厂
*/
class MideaFactory implements AbstractFactory {
// 实现创建电视的方法
@Override
public TelevisionProduct createTelevisionProduct() {
return new MideaTelevisionProduct();
}
// 创建冰箱的方法
@Override
public RefrigeratorProduct createRefrigeratorProduct() {
return new MideaRefrigeratorProduct();
}
}
/**
* 海尔生产工厂
*/
class HairFactory implements AbstractFactory {
// 实现创建电视的方法
@Override
public TelevisionProduct createTelevisionProduct() {
return new HairTelevisionProduct();
}
// 创建冰箱的方法
@Override
public RefrigeratorProduct createRefrigeratorProduct() {
return new HairRefrigeratorProduct();
}
}
// 产品簇-冰箱产品
public interface RefrigeratorProduct {
void displayColor();
}
// 产品簇-电视机产品
public interface TelevisionProduct {
void displayShape();
}
// 海尔冰箱
public class HairRefrigeratorProduct implements RefrigeratorProduct {
@Override
public void displayColor() {
System.out.println("海尔冰箱");
}
}
// 海尔电视机
public class HairTelevisionProduct implements TelevisionProduct{
@Override
public void displayShape() {
System.out.println("海尔电视机");
}
}
// 美的冰箱
public class MideaRefrigeratorProduct implements RefrigeratorProduct {
@Override
public void displayColor() {
System.out.println("美的冰箱");
}
}
// 美的电视机
public class MideaTelevisionProduct implements TelevisionProduct{
@Override
public void displayShape() {
System.out.println("美的电视机");
}
}
class Client {
public static void main(String[] args) {
// 美的工厂的产品簇
AbstractFactory mideaFactory = new MideaFactory();
RefrigeratorProduct mideaRefrigerator = mideaFactory.createRefrigeratorProduct();
mideaRefrigerator.displayColor();
TelevisionProduct mideaTelevision = mideaFactory.createTelevisionProduct();
mideaTelevision.displayShape();
System.out.println("========分割线========");
// 海尔工厂的产品簇
HairFactory hairFactory = new HairFactory();
RefrigeratorProduct hairRefrigerator = hairFactory.createRefrigeratorProduct();
hairRefrigerator.displayColor();
TelevisionProduct hairTelevision = hairFactory.createTelevisionProduct();
hairTelevision.displayShape();
}
}
美的冰箱
美的电视机
========分割线========
海尔冰箱
海尔电视机
?基于上面的这个抽象工厂的Demo,我们来画一下抽象工厂模式的UML类图。
?抽象工厂模式是工厂方法模式的进一步延伸,在一些框架和API的类库设计中都得到了广泛的使用。下面,我们来总结一下这种设计模式的优缺点
?抽象工作的缺点也很明显,像扩展产品分类是比较麻烦的,涉及到多个接口和类的关联修改,违背了开闭原则。