设计模式系列(三):抽象工厂模式

接着上一文的工厂方法模式,咱们的水果店继续蓬勃发展,水果种类越来越多。

比如,之前卖的苹果,现在会有红富士、黄元帅、青苹果多种种类;桃子会有油桃,水蜜桃,黄桃;梨子也会有砂糖梨,香梨,雪梨。

这时候,我们就需要抽象工厂来帮我们解决这个需求。

实现

以苹果为例,它这里是一个抽象产品类

1
2
3
public abstract class IApple {
public abstract void description();
}

接着是具体产品类,显然这里是具体的各种水果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class RedApple extends IApple {
@Override
public void description() {
Log.d("Chen", "红富士,12块一斤");
}
}

public class YellowApple extends IApple {
@Override
public void description() {
Log.d("Chen", "黄元帅,10块一斤");
}
}

public class GreenApple extends IApple {
@Override
public void description() {
Log.d("Chen", "青苹果,8块一斤");
}
}

可以明显地看出,工厂方法模式是生产单个同类型的不同产品,而抽象工厂模式生产的是多个不同类型的不同产品,所以必须将共同点抽象出来。

抽象工厂类:我们的水果店。

1
2
3
4
5
public abstract class FoodFactory {
public abstract IApple createApple(int type);
public abstract IPeach createPeach(int type);
public abstract IPear createPear(int type);
}

具体工厂类:以具体的第一水果分店为例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class FruitFactoryOne extends FruitFactory{
public static final int TYPE_RED = 1; // 红富士
public static final int TYPE_YELLOW = 2; // 黄元帅
public static final int TYPE_GREEN = 3; // 青苹果

@Override
public IApple creatApple(int type) {
if (type == TYPE_RED) {
return new RedApple();
} else if (type == TYPE_YELLOW) {
return new YellowApple();
} else if (type == TYPE_GREEN) {
return new GreenApple();
} else {
throw new IllegalArgumentException("Wrong type.");
}
}

// 创建具体桃子,梨子的方法与苹果类似
...
}

最后是调用:

1
2
3
FruitFactory factory = new FruitFactoryOne();
IApple apple = factory.creatApple(FruitFactoryOne.TYPE_YELLOW);
apple.description();

输出结果:

1
D/Chen: 黄元帅,10块一斤

总结

老规矩,讲完了基本的结构,作一下最后总结。

抽象工厂与工厂方法的差别

普通工厂产出是一个产品,抽象工厂产出是一个抽象。区别在于,若添加一个新的产品,前者是修改工厂,后者是创建新工厂。

所以在抽象工厂模式中,增加一个产品族(比如再加一个橘柑种类)很容易,而增加一个产品等级结构(比如在苹果类里再加一个嘎啦果的子类)却很难,工厂模式则反之。

也就是说,在抽象工厂模式中,增加一个具体的工厂很容易。但是你想在工厂中多生产一种产品,就需要修改很多个类,会违背开闭原则,这种情况下应该使用工厂模式。

优点

  • 面向接口编程,使创建对象从具体的产品实现中解耦。

  • 在切换产品类时更加灵活。

缺点

  • 类文件爆炸。

  • 不容易扩展新的具体产品类。

抽象工厂模式:为创建一组相关或者是相互依赖的对象提供一个接口,而不需要指定它们的具体类

Chen wechat
欢迎扫描二维码,订阅我的博客公众号MiracleChen