设计模式—抽象工厂模式详解

前言

在上文提到的最易懂的设计模式系列解析:工厂方法模式,发现工厂方法模式存在一个严重的问题:一个具体工厂只能创建一类产品而在实际过程中,一个工厂往往需要生产多类产品。

为了解决上述的问题,我们又使用了一种新的设计模式:抽象工厂模式。

UML类图

在这里插入图片描述

  1. 抽象工厂模式中存在四种角色,分别是抽象工厂角色,具体工厂角色,抽象产品角色,具体产品角色。
  2. 抽象工厂角色:担任这个角色的是工厂方法模式的核心,它是与应用系统商业逻辑无关的。
  3. 具体工厂角色:这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。
  4. 抽象产品角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。
  5. 具体产品角色:抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。
定义

抽象工厂模式,即Abstract Factory Pattern,提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类;具体的工厂负责实现具体的产品实例。

抽象工厂模式与工厂方法模式最大的区别:抽象工厂中每个工厂可以创建多种类的产品,而工厂方法每个工厂只能创建一类

主要作用

允许使用抽象的接口来创建一组相关产品,而不需要知道或关心实际生产出的具体产品是什么,这样就可以从具体产品中被解耦。

解决的问题

每个工厂只能创建一类产品。

案例

完成步骤

1、 创建抽象工厂类,定义具体工厂的公共接口;
2、 创建抽象产品族类 ,定义抽象产品的公共接口;
3、创建抽象产品类 (继承抽象产品族类),定义具体产品的公共接口;
4、创建具体产品类(继承抽象产品类) & 定义生产的具体产品;
5、创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;
6、客户端通过实例化具体的工厂类,并调用其创建不同目标产品的方法创建不同具体产品类的实例。

实例概况

背景:小成有两间塑料加工厂(A厂仅生产容器类产品;B厂仅生产模具类产品);随着客户需求的变化,A厂所在地的客户需要也模具类产品,B厂所在地的客户也需要容器类产品;
痛点:没有资源(资金+租位)在当地分别开设多一家注塑分厂
解决方案:在原有的两家塑料厂里增设生产需求的功能,即A厂能生产容器+模具产品;B厂间能生产模具+容器产品。

代码展示

步骤1: 创建抽象工厂类,定义具体工厂的公共接口:

abstract class Factory{
   public abstract Product ManufactureContainer();
    public abstract Product ManufactureMould();
}

步骤2: 创建抽象产品族类 ,定义具体产品的公共接口:

abstract class AbstractProduct{
    public abstract void Show();
}

步骤3: 创建抽象产品类 ,定义具体产品的公共接口:

//容器产品抽象类
abstract class ContainerProduct extends AbstractProduct{
    @Override
    public abstract void Show();
}

//模具产品抽象类
abstract class MouldProduct extends AbstractProduct{
    @Override
    public abstract void Show();
}

步骤4: 创建具体产品类(继承抽象产品类), 定义生产的具体产品;

//容器产品A类
class ContainerProductA extends ContainerProduct{
    @Override
    public void Show() {
        System.out.println("生产出了容器产品A");
    }
}

//容器产品B类
class ContainerProductB extends ContainerProduct{
    @Override
    public void Show() {
        System.out.println("生产出了容器产品B");
    }
}

//模具产品A类
class MouldProductA extends MouldProduct{

    @Override
    public void Show() {
        System.out.println("生产出了模具产品A");
    }
}

//模具产品B类
class MouldProductB extends MouldProduct{

    @Override
    public void Show() {
        System.out.println("生产出了模具产品B");
    }
}

步骤5:创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法:

//A厂 - 生产模具+容器产品
class FactoryA extends Factory{

    @Override
    public Product ManufactureContainer() {
        return new ContainerProductA();
    }

    @Override
    public Product ManufactureMould() {
        return new MouldProductA();
    }
}

//B厂 - 生产模具+容器产品
class FactoryB extends Factory{

    @Override
    public Product ManufactureContainer() {
        return new ContainerProductB();
    }

    @Override
    public Product ManufactureMould() {
        return new MouldProductB();
    }
}

步骤6:客户端通过实例化具体的工厂类,并调用其创建不同目标产品的方法创建不同具体产品类的实例:

//生产工作流程
public class AbstractFactoryPattern {
    public static void main(String[] args){
        FactoryA mFactoryA = new FactoryA();
        FactoryB mFactoryB = new FactoryB();
        //A厂当地客户需要容器产品A
        mFactoryA.ManufactureContainer().Show();
        //A厂当地客户需要模具产品A
        mFactoryA.ManufactureMould().Show();

        //B厂当地客户需要容器产品B
        mFactoryB.ManufactureContainer().Show();
        //B厂当地客户需要模具产品B
        mFactoryB.ManufactureMould().Show();

    }
}
结果
生产出了容器产品A
生产出了容器产品B
生产出了模具产品A
生产出了模具产品B

优点

1、降低耦合:抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而使系统耦合度低,这样更有利于后期的维护和扩展;

2、更符合开-闭原则:新增一种产品类时,只需要增加相应的具体产品类和相应的工厂子类即可,简单工厂模式需要修改工厂类的判断逻辑;

3、符合单一职责原则:每个具体工厂类只负责创建对应的产品,简单工厂中的工厂类存在复杂的switch逻辑判断;

4、不使用静态工厂方法,可以形成基于继承的等级结构,简单工厂模式的工厂类使用静态工厂方法。

缺点

抽象工厂模式很难支持新种类产品的变化。这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开发——封闭”原则。

对于新的产品族符合开-闭原则;对于新的产品种类不符合开-闭原则,这一特性称为开-闭原则的倾斜性。

应用场景

在了解了优缺点后,我总结了工厂方法模式的应用场景:

1、一个系统不要求依赖产品类实例如何被创建、组合和表达的表达,这点也是所有工厂模式应用的前提;
2、这个系统有多个系列产品,而系统中只消费其中某一系列产品;
3、系统要求提供一个产品类的库,所有产品以同样的接口出现,客户端不需要依赖具体实现。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值