为创建一组相关或者是相互依赖的对象提供一个接口,而不需要指定他们的具体实现类。
一个对象族(或是一组没有任何关系的对象)都有相同的约束,则可以使用抽象工厂模式。例如一个文本编辑器和一个图片处理器,都是软件实体,但是Linix下的文本编辑器和WINDOWS下的文本编辑器虽然功能和界面都相同,但是代码实现是不同的,图片处理器也是类似情况,也就是具有了共同的约束条件:操作系统类型,于是我们可以使用抽象工厂模式,产生不同操作系统下的编辑器和图片处理器。
以车厂生产汽车零部件为例,A、B两家车厂分别生产不同的轮胎、发动机、制动系统。虽然生产的零件不同,型号不同。但是根本上都有共同的约束,就是轮胎、发动机、制动系统。
轮胎相关类:
public interface ITire {
/** * 轮胎 */
void tire();
}
public class NormalTire implements ITire{
@Override
public void tire() {
System.out.println("普通轮胎");
}
}
public class SUVTire implements ITire{
@Override
public void tire() {
System.out.println("越野轮胎");
}
}
发动机相关类:
public interface IEngine {
/** *发动机 */
void engine();
}
public class DomesticEngine implements IEngine{
@Override
public void engine() {
System.out.println("国产发动机");
}
}
public class ImportEngine implements IEngine{
@Override
public void engine() {
System.out.println("进口发动机");
}
}
制动系统相关类:
public interface IBrake {
/** *制动系统 */
void brake();
}
public class NormalBrake implements IBrake{
@Override
public void brake() {
System.out.println("普通制动");
}
}
public class SeniorBrake implements IBrake{
@Override
public void brake() {
System.out.println("高级制动");
}
}
抽象车厂类:
public abstract class CarFactory {
/** * 生产轮胎 * * @return 轮胎 * */
public abstract ITire createTire();
/** * 生产发动机 * * @return 发动机 * */
public abstract IEngine createEngine();
/** * 生产制动系统 * * @return 制动系统 * */
public abstract IBrake createBrake();
}
A车厂:
public class AFactory extends CarFactory{
@Override
public ITire createTire() {
return new NormalTire();
}
@Override
public IEngine createEngine() {
return new DomesticEngine();
}
@Override
public IBrake createBrake() {
return new NormalBrake();
}
}
B车厂:
public class BFactory extends CarFactory{
@Override
public ITire createTire() {
return new SUVTire();
}
@Override
public IEngine createEngine() {
return new ImportEngine();
}
@Override
public IBrake createBrake() {
return new SeniorBrake();
}
}
客户类:
public class Client {
public static void main(String[] args) {
//A车厂
CarFactory factoryA = new AFactory();
factoryA.createTire().tire();
factoryA.createEngine().engine();
factoryA.createBrake().brake();
System.out.println("---------------");
//B车厂
CarFactory factoryB = new BFactory();
factoryB.createTire().tire();
factoryB.createEngine().engine();
factoryB.createBrake().brake();
}
}
结果:
普通轮胎
国产发动机
普通制动 ------------------
越野轮胎
进口发动机
高级制动
可以看出上面模拟了两个车厂,如果有了C厂、D厂,各自厂家生产的零部件型号种类又不相同,那么我们创建的类文件就会翻倍。这也是抽象工厂模式的一个弊端,所以实际开发中要权衡使用。
上一章有介绍了工厂模式,那么他们的区别是什么?抽象工厂模式是工厂方法模式的升级版本。对比如下:
工厂方法模式 | 抽象工厂模式 |
---|---|
只有一个抽象产品类 | 有多个抽象产品类 |
具体工厂类只能创建一个具体产品类的实例 | 具体工厂类能创建多个具体产品类的实例 |
抽象工厂模式在Android源码中使用较少,因为很少会出现多个产品种类的情况,大部分使用工厂方法模式即可解决。
MediaPlayer Factory分别会生成4个不同的MediaPlayer基类:StagefrightPlayer、NuPlayerDriver、MidiFile和TestPlayerStub,四者均继承于MediaPlayerBase。
优点:
分离接口与实现,客户端使用抽象工厂来创建需要的对象,而客户端根本就不知道具体的实现是谁,客户端只是面向产品的接口编程而已,使其从具体的产品实现中解耦,同时基于接口与实现分离,使抽象该工厂方法模式在切换产品类时更加灵活、容易。
缺点:
一是对类文件的爆炸性增加,二是不太容易扩展新的产品类。
参考链接:抽象工厂模式