Java设计模式(四)抽象工厂模式

文章目录

    • 抽象工厂模式
      • 介绍
        • 代码实现
        • 抽象工厂的优缺点
        • 小结(应用场景)
    • 简单工厂、工厂方法、抽象工厂区别

抽象工厂模式

介绍

抽象工厂模式可以说是是工厂方法模式的升级版,当需要创建的产品有多个产品线(产品族)时,使用抽象工厂模式是比较好的选择。

简单地说就是工厂的工厂,抽象工厂可以创建具体工厂,由具体工厂来产生具体产品。
Java设计模式(四)抽象工厂模式_第1张图片
Java设计模式(四)抽象工厂模式_第2张图片

在抽象工厂模式中有如下角色:

  • AbstractFactory:抽象工厂,它声明了用来创建不同产品的方法。
  • ConcreteFactory:具体工厂,实现抽象工厂中定义的创建产品的方法。
  • AbstractProduct:抽象产品,为每种产品声明业务方法。
  • ConcreteProduct:具体产品,定义具体工厂生产的具体产品,并实现抽象产品中定义的业务方法。

代码实现

场景:

  1. 现在有2个产品族,一个水果,一个必需品
  2. 水果有2种,苹果,香蕉
  3. 必需品也有2种,大米,盐
  4. 工厂生产的东西必须包含一种水果,一种必需品

产品族

public interface AbstractFruit {
    void produceFruit();
}

public interface AbstractNecessities {
    void produceNecessities();
}

具体产品

// 具体产品1(苹果)
public class AppleA implements AbstractFruit{
    @Override
    public void produceFruit() {
        System.out.println("抽象工厂...生产水果...apple...");
    }
}

// 具体产品2(香蕉)
public class BananaA implements AbstractFruit {
    @Override
    public void produceFruit() {
        System.out.println("抽象工厂...生产水果...banana...");
    }
}

// 具体产品3(盐)
public class SaltA implements AbstractNecessities {
    @Override
    public void produceNecessities() {
        System.out.println("抽象工厂...生产必需品...salt...");
    }
}

// 具体产品4(大米)
public class RiceA implements AbstractNecessities {
    @Override
    public void produceNecessities() {
        System.out.println("抽象工厂...生产必需品...rice...");
    }
}

以上是纵向关系,苹果、香蕉继承于水果,盐、大米继承于必需品

现在构建工厂,首先一个父工厂(抽象工厂),然后两个具体工厂

// 定义 生产 产品工厂 的抽象工厂
public interface AbstractFactory {
    AbstractFruit produceFruit();
    AbstractNecessities produceNecessities();
}

2个具体工厂

// 具体工厂1号,本工厂职责:只生产苹果和盐
public class AppleAndSaltFactory implements AbstractFactory {
    @Override
    public AbstractFruit produceFruit() {
        return new AppleA();
    }

    @Override
    public AbstractNecessities produceNecessities() {
        return new SaltA();
    }
}

// 具体工厂2号,本工厂职责:只生产香蕉和大米
public class BananaAndRiceFactory implements AbstractFactory {
    @Override
    public AbstractFruit produceFruit() {
        return new BananaA();
    }

    @Override
    public AbstractNecessities produceNecessities() {
        return new RiceA();
    }
}

工厂的使用

public class AbstractClient {
    public static void main(String[] args) {
        AbstractFactory appleAndSaltFactory = new AppleAndSaltFactory();
        appleAndSaltFactory.produceFruit().produceFruit();
        appleAndSaltFactory.produceNecessities().produceNecessities();

        AbstractFactory bananaAndRiceFactory = new BananaAndRiceFactory();
        bananaAndRiceFactory.produceFruit().produceFruit();
        bananaAndRiceFactory.produceNecessities().produceNecessities();
    }
}

/*	运行结果
抽象工厂...生产水果...apple...
抽象工厂...生产必需品...salt...
抽象工厂...生产水果...banana...
抽象工厂...生产必需品...rice...
*/

抽象工厂的优缺点

优点

  1. 抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。
  2. 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。这对一些需要根据当前环境来决定其行为的软件系统来说,是一种非常实用的设计模式。
  3. 增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。

缺点

  1. 在添加新的产品对象时,难以扩展抽象工厂来生产新种类的产品。因为在抽象工厂角色中规定了所有可能被创建的产品集合,要支持新种类的产品就意味着要对该接口进行扩展,而这将涉及到对抽象工厂角色及其所有子类的修改,显然会带来较大的不便
  2. 使用抽象工厂模式要求设计人员在设计之初就能够全面考虑,不会在设计完成之后向系统中增加新的产品等级结构,也不会删除已有的产品等级结构,否则将会导致系统出现较大的修改,为后续维护工作带来诸多麻烦。

小结(应用场景)

先看优缺点!

这个例子有点欠佳,看到这里,如果还不明白抽象工厂,接下来举一个进行扩展的例子,你应该就可以明白了。

1. 横向拓展易

如果增加新的具体工厂(就是所谓的产品族),比如,新增一个 只生产苹果和大米的工厂。

​ 那么,不需要修改原有的代码,只需要新增一个工厂类 AppleAndRiceFactory implements AbstractFactory 即可。

2. 纵向扩展难

比如,新增一类产品 — 家电(相当于新增具体的产品)。

​ 要想工厂具有生产家电的功能,就需要修改 AbstractFactory 的代码,新增加一个生产家电的方法,那么就需要重新构建所有实现了 AbstractFactory 接口的类,极为复杂。

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

简单工厂 : 用来生产同一等级结构中的任意产品。(不支持拓展增加产品)

工厂方法 :用来生产同一等级结构中的固定产品。(支持拓展增加产品)

抽象工厂 :用来生产不同产品族的全部产品。(不支持拓展增加产品;支持增加产品族)

工厂设计模式

Java设计模式(二)简单工厂模式—设计模式六大原则
Java设计模式(三)工厂方法模式

你可能感兴趣的:(设计模式)