创建型设计模式之抽象工厂方法模式

本文深入讲解抽象工厂模式的概念、应用场景及其实现方式,并通过汽车配件生产实例进行详细说明。此外,还对比了简单工厂、工厂方法与抽象工厂的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 抽象工厂方法模式概念

1.1 介绍

随着客户的要求越来越高,宝马车需要不同配置的空调和发动机等配件。于是这个工厂开始生产空调和发动机,用来组装汽车。这时候工厂有两个系列的产品:空调和发动机。宝马320系列配置A型号空调和A型号发动机,宝马230系列配置B型号空调和B型号发动机。
抽象工厂模式是工厂方法模式的升级版本,他用来创建一组相关或者相互依赖的对象。比如宝马320系列使用空调型号A和发动机型号A,而宝马230系列使用空调型号B和发动机型号B,那么使用抽象工厂模式,在为320系列生产相关配件时,就无需制定配件的型号,它会自动根据车型生产对应的配件型号A。

1.2 定义

为创建一组相关或者是相互依赖的对象提供一个接口,而不需要指定他们的具体实现类。

1.3 使用场景

一个对象族(或是一组没有任何关系的对象)都有相同的约束,则可以使用抽象工厂模式。例如:Linix和Windows下都有文本编辑器图片处理器,两者都属于Software软件的范畴,但是他们所在的操作系统不一样,代码的实现逻辑实现也是不同的,也就是具有了共同的约束条件:操作系统类型。于是我们可以使用抽象工厂模式,产生不同操作系统下的编辑器和图片处理器。

2 原型模式UML类图通用

这里写图片描述
或者
这里写图片描述

3 通用模式代码

(1)抽象产品类A

public abstract class AbstractProductA { 
	// 每个具体产品子类需要实现的方法
	public abstract void method();
}

(2)抽象产品类B

public abstract class AbstractProductB { 
	// 每个具体产品子类需要实现的方法
	public abstract void method();
}

(3)具体产品类A1

public class ConcreteProductA1 extends AbstractProductA {
	@Override
	public void method() { 
		System.out.println("具体产品类A1的实现方法");
	}
}

(4)具体产品类A2

public class ConcreteProductA2 extends AbstractProductA {
	@Override
	public void method() { 
		System.out.println("具体产品类A2的实现方法");
	}
}

(5)具体产品类B1

public class ConcreteProductB1 extends AbstractProductB {
	@Override
	public void method() { 
		System.out.println("具体产品类B1的实现方法");
	}
}

(6)具体产品类B2

public class ConcreteProductB2 extends AbstractProductB {
	@Override
	public void method() { 
		System.out.println("具体产品类B2的实现方法");
	}
}

(7)抽象工厂类

public abstract class AbstractFactory { 
	// 创建A产品家族
	public abstract AbstractProductA createProductA(); 
	//创建B产品家族
	public abstract AbstractProductB createProductB();
}

(8)具体工厂类1

public class ConcreteFactory1 extends AbstractFactory {
	// 只生产产品等级为1的A产品
	public AbstractProductA createProductA() {
		return new ConcreteProductA1();
	}

	// 只生产产品等级为1的B产品
	public AbstractProductB createProductB() {
		return new ConcreteProductB1();
	}
}

(9)具体工厂类2

public class ConcreteFactory2 extends AbstractFactory {
	// 只生产产品等级为2的A产品
	public AbstractProductA createProductA() {
		return new ConcreteProductA2();
	}

	// 只生产产品等级为2的B产品
	public AbstractProductB createProductB() {
		return new ConcreteProductB2();
	}
}

4 Android源码中的原型模式

抽象工厂模式在Android源码中使用较少,因为很少会出现多个产品种类的情况,大部分使用工厂方法模式即可解决。
(1)MediaPlayer:MediaPlayer Factory分别会生成4个不同的MediaPlayer基类:StagefrightPlayer、NuPlayerDriver、MidiFile和TestPlayerStub,四者均继承于MediaPlayerBase。

5 抽象工厂方法模式实战

虽然Q3、Q5、Q7都是一个车系,但是三者之间的零部件差别却是很大,例如,Q3使用的发动机是国产的,而Q7则是原装进口的;Q3轮胎是普通的轮胎,而Q7则使用的是全尺寸越野轮胎;还有Q3使用的是比较普通的制动系统,而Q7则使用的是制动性能极好的制动系统。Q3、Q7对应的是一系列车,而轮胎、发动机、制动系统则对应的是一系列零部件,两者是两种不同的产品类型,这时候就可以将抽象工厂模式应用到其中。首先汽车工厂需要生产轮胎、发动机、制动系统这3中部件。
(1)轮胎相关类

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("越野轮胎");
    }
}

(2)发动机相关类

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("进口发动机");
    }
}

(3)制动系统相关类

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("高级制动");
    }
}

(4)抽象车厂类

public abstract class CarFactory {
    /**
     * 生产轮胎
     * 
     * @return 轮胎
     * */
    public abstract ITire createTire();

    /**
     * 生产发动机
     * 
     * @return 发动机
     * */
    public abstract IEngine createEngine();

    /**
     * 生产制动系统
     * 
     * @return 制动系统
     * */
    public abstract IBrake createBrake();

}

(5)Q3工厂类

public class Q3Factory extends CarFactory{

    @Override
    public ITire createTire() {
        return new NormalTire();
    }

    @Override
    public IEngine createEngine() {
        return new DomesticEngine();
    }

    @Override
    public IBrake createBrake() {
        return new NormalBrake();
    }
}

(6)Q7工厂类

public class Q7Factory extends CarFactory{

    @Override
    public ITire createTire() {
        return new SUVTire();
    }

    @Override
    public IEngine createEngine() {
        return new ImportEngine();
    }

    @Override
    public IBrake createBrake() {
        return new SeniorBrake();
    }
}

(7)客户类

public class Client {
    public static void main(String[] args) {
        //Q3工厂类
        CarFactory factoryQ3 = new Q3Factory();
        factoryQ3.createTire().tire();
        factoryQ3.createEngine().engine();
        factoryQ3.createBrake().brake();
        System.out.println("---------------");
        
        //Q7工厂类
        CarFactory factoryQ7 = new Q7Factory();
        factoryQ7.createTire().tire();
        factoryQ7.createEngine().engine();
        factoryQ7.createBrake().brake();
    }
}

(8)结果打印

普通轮胎
国产发动机
普通制动
------------------
越野轮胎
进口发动机
高级制动

可以看出上面模拟了两个工厂,如果有了Q5厂、Q9厂,各自厂家生产的零部件型号种类又不相同,那么我们创建的类文件就会翻倍。这也是抽象工厂模式的一个弊端,所以实际开发中要权衡使用。

6 简单工厂、工厂方法、抽象工厂之区别

简单工厂,工厂方法,抽象工厂都属于设计模式中的创建型模式。其主要功能都是帮助我们把对象的实例化部分抽取了出来,优化了系统的架构,并且增强了系统的扩展性。

6.1 区别

(1)简单工厂模式:一个抽象产品类,可以派生出多个具体产品类。一个具体工厂类,通过往此工厂的static方法中传入不同参数,产出不同的具体产品类实例。
(2)工厂方法模式:一个抽象产品类,可以派生出多个具体产品类。一个抽象工厂类,可以派生出多个具体工厂类。每个具体工厂类只能创建一个具体产品类的实例。
(3)抽象工厂模式: 多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。 一个抽象工厂类,可以派生出多个具体工厂类。 每个具体工厂类可以创建多个具体产品类的实例。

6.2 举例说明

用种蔬菜的例子来说明事实,最初的时候,由于规模小,只种植一种蔬菜,根菜类蔬菜,这个时候由于种植方式比较简单,采用简单工厂模式即可,主要目的是让工人轻松,下达工厂种植即可。
但是随着种植厂的发展以及市场的需求,要增加一种蔬菜类型种植——茎菜,由于茎菜与根菜种植方式不一致,就需要两个专门的种植工厂来进行管理,那么久采用工厂模式来管理,一个工厂负责一种作物的种植,这个时候产品可以理解为仍然在一个层次。我用UML图表示三种结构:
(1)简单工厂

[外链图片转存失败(img-qA6ZBIxT-1564814653151)(https://img-my.youkuaiyun.com/uploads/201005/16/0_1274005023Bb8F.gif)]

(2)工厂方法

[外链图片转存失败(img-oAb3JWGy-1564814653152)(https://img-my.youkuaiyun.com/uploads/201005/16/0_1274005025vcH6.gif)]

(3)抽象工厂

[外链图片转存失败(img-X7X3FzGa-1564814653154)(https://img-my.youkuaiyun.com/uploads/201005/16/0_1274005028mzy7.gif)]

(4)小结

在没一个层次,种菜工人所关心的对象也不一样,在简单工厂模式下,工人要想到种植萝卜还是白菜,在工厂模式下,工人想到是种植根菜还是茎菜,而在抽象工厂模式下,则关心种植基因菜还是非基因菜

7 总结

(1)优点

分离接口与实现,客户端使用抽象工厂来创建需要的对象,而客户端根本就不知道具体的实现是谁,客户端只是面向产品的接口编程而已,使其从具体的产品实现中解耦,同时基于接口与实现分离,使抽象该工厂方法模式在切换产品类时更加灵活、容易。

(2)缺点

一是对类文件的爆炸性增加,二是不太容易扩展新的产品类。

8 参考文章与链接

《Android源码设计模式解析与实战》

《设计模式之禅》

《Android源码设计模式解析与实战》读书笔记(六)

设计模式:简单工厂、工厂方法、抽象工厂之小结与区别

抽象工厂模式和工厂方法模式区别

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值