1. 简介
定义:为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类
与工厂方法模式不同(工厂方法的升级,在工厂方法模式中每个实际的工厂只定义了一个工厂方法),抽象工厂模式能够应对更加复杂的产品族系,它更类似于一种对“工业制造标准”的制定与推行,各工厂实现都遵循此标准来进行生产活动,有M个产品系列就应该有M个实现工厂类,在每个实现工厂中,实现不同产品族的生产任务,达到无限扩展产品的目的
总的来说,一个工厂完成一系产品(A1 B1是1个系列)的加工,在一个工厂内部,根据方法的不同来区分不同类产品的加工(比如A1 B1不同类同系)
2. 代码实例
以和设计模式详解(三)工厂模式中的造人例子类似,现在引入以下场景:
在三中,是创建黑白黄三种人,现在要求再加入一个性别分类,即黑白黄+男女,一共六种,如果按照工厂方法来的话,需要创建6个子类和6个工厂,实现类太多,如果后面还需要加入其他的分类条件,可以会出现组合爆炸的情况,因此采用抽象工厂模式的类图如下:
package designpattern;
/*
*
* 人类抽象类
*/
abstract class Human {
public abstract void color();
public abstract void talk();
}
abstract class BlackHuman extends Human{
@Override
public void color() {
System.out.println("我的皮肤是黑色");
}
abstract public void talk();
}
abstract class YellowHuman extends Human{
@Override
public void color() {
System.out.println("我的皮肤是黄色");
}
abstract public void talk();
}
abstract class WhiteHuman extends Human{
@Override
public void color() {
System.out.println("我的皮肤是白色");
}
abstract public void talk();
}
class FemaleBlackMan extends BlackHuman{
@Override
public void talk() {
System.out.println("我是黑人女性");
}
}
class FemaleWhiteMan extends WhiteHuman{
@Override
public void talk() {
System.out.println("我是白人女性");
}
}
class FemaleYellowMan extends YellowHuman{
@Override
public void talk() {
System.out.println("我是黄人女性");
}
}
class MaleBlackMan extends BlackHuman{
@Override
public void talk() {
System.out.println("我是黑人男性");
}
}
class MaleWhiteMan extends WhiteHuman{
@Override
public void talk() {
System.out.println("我是白人男性");
}
}
class MaleYellowMan extends YellowHuman{
@Override
public void talk() {
System.out.println("我是黄人男性");
}
}
interface HumanFactory{
public Human createBlackHuman();
public Human createWhiteHuman();
public Human createYellowHuman();
}
class FemaleHumanFactory implements HumanFactory{
@Override
public Human createBlackHuman() {
return new FemaleBlackMan();
}
@Override
public Human createWhiteHuman() {
return new FemaleWhiteMan();
}
@Override
public Human createYellowHuman() {
return new FemaleYellowMan();
}
}
class MaleHumanFactory implements HumanFactory{
@Override
public Human createBlackHuman() {
return new MaleBlackMan();
}
@Override
public Human createWhiteHuman() {
return new MaleWhiteMan();
}
@Override
public Human createYellowHuman() {
return new MaleYellowMan();
}
}
public class AbstractFactoryDemo {
public static void main(String[] args) {
//男性生产线
HumanFactory maleHumanFactory=new MaleHumanFactory();
//女性生产线
HumanFactory femaleHumanFactory=new FemaleHumanFactory();
Human maleBlack=maleHumanFactory.createBlackHuman();//创建黑人男性
Human femaleWhite=femaleHumanFactory.createWhiteHuman();//创建白人女性
maleBlack.color();
maleBlack.talk();
femaleWhite.color();
femaleWhite.talk();
}
}
上面的代码中,分为
3. 抽象工厂的优缺点
优点:
- 封装性。每个产品的实现类不是高层模块要关心的,它要关心的是接口
- 产品族内的约束为非公开状态
缺点:
- 产品族扩展非常困难。如果要增加一个产品C,也就是说产品家族由原来的2个增加到3个,抽象类AbstractCreator要增加一个方法createProductC(),然后之前的两个实现类都要修改
产品族(人的肤色)扩展困难,而不是产品等级(性别):比如再增加一个第三性别X,则要增加三个产品类,分别对应性别X下不同的肤色,然后再创建一个工厂类。这是比较简单的;
但是如果再增加一个棕色人(族),则需要在抽象工厂中添加一个生产棕色人种方法,并且要修改之前已经实现抽象类的两个具体类,违反了开闭原则,问题的本质在于工厂内部用不同的方法区别于不同的族,增加族就要改变抽象工厂内部的方法