前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java设计模式-工厂模式(3)抽象工厂模式

Java设计模式-工厂模式(3)抽象工厂模式

作者头像
宁在春
发布2022-10-31 15:05:37
2710
发布2022-10-31 15:05:37
举报
文章被收录于专栏:关于Java学习@宁在春

Java设计模式-工厂模式(2)工厂方法模式 我们知道了工厂方法模式解决了简单工厂模式中的缺陷,做到了满足开闭原则,但是时代是进步的,进而又产生新的问题,工厂难道只能生产一种东西吗。我们所见到的工厂大都都是综合性的。所以就有了抽象工厂模式。

放张图舒缓一下心情。

Java设计模式-工厂模式(3)抽象工厂模式

代码语言:txt
复制
- [一、前言](https://cloud.tencent.com/developer)
    - [1)概述:](https://cloud.tencent.com/developer)
    - [2)角色概述:](https://cloud.tencent.com/developer)
    - [3)前文](https://cloud.tencent.com/developer)
- [二、代码实现](https://cloud.tencent.com/developer)
    - [1)抽象产品及具体产品:](https://cloud.tencent.com/developer)
    - [2)抽象工厂 及具体工厂](https://cloud.tencent.com/developer)
    - [3)测试](https://cloud.tencent.com/developer)
    - [4)优缺点:](https://cloud.tencent.com/developer)
    - [5)使用场景:](https://cloud.tencent.com/developer)
- [三、自言自语](https://cloud.tencent.com/developer)

一、前言

1)概述:

  1. 抽象工厂模式(Abstract Factory Pattern)隶属于设计模式中的创建型模式,用于产品族的构建。抽象工厂是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂是指当有多个抽象角色时使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象。
  2. 工厂模式中的每一个形态都是针对一定问题的解决方案,工厂方法针对的是多个产品系列结构;而抽象工厂模式针对的是多个产品族结构,一个产品族内有多个产品系列。
  3. 抽象工厂模式相对于工厂方法模式来说,就是工厂方法模式是针对一个产品系列的,而抽象工厂模式是针对多个产品系列的,即工厂方法模式是一个产品系列一个工厂类,而抽象工厂模式是多个产品系列一个工厂类
  4. 如果客户端需要创建一些产品结构,而这些产品结构又分别属于不同的产品类别,则可以使用抽象工厂模式,抽象工厂模式中抽象工厂类负责定义创建对象的接口,具体这一系列对象的创建工作由实现抽象工厂的具体工厂类来完成。

2)角色概述:

抽象工厂模式中存在四种角色,分别是抽象工厂角色,具体工厂角色,抽象产品角色,具体产品角色。

  • 抽象工厂:提供了创建产品的接口,它包含多个创建产品的方法,可以创建多个不同等级的产品。
  • 具体工厂:主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
  • 抽象产品:定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
  • 具体产品:实现了抽象产品角色所定义的接口,由具体工厂来创建,它 同具体工厂之间是多对一的关系。

3)前文

在这里再次上一篇文章中👉Java设计模式-工厂模式(2)工厂方法模式 中出现的问题再做一次扩展。

原问题是:

需求:设计一个咖啡店点餐系统。

设计一个咖啡类(Coffee),并定义其两个子类(美式咖啡【AmericanCoffee】和拿铁咖啡【LatteCoffee】);再设计一个咖啡店类(CoffeeStore),咖啡店具有点咖啡的功能。

但是现在我们咖啡店进行扩张了。

现咖啡店业务发生改变,不仅要生产咖啡还要生产甜点,如提拉米苏、抹茶慕斯等,要是按照工厂方法模式,需要定义提拉米苏类、抹茶慕斯类、提拉米苏工厂、抹茶慕斯工厂、甜点工厂类,很容易发生类爆炸情况。其中拿铁咖啡、美式咖啡是一个产品等级,都是咖啡;提拉米苏、抹茶慕斯也是一个产品等级;拿铁咖啡和提拉米苏是同一产品族(也就是都属于意大利风味),美式咖啡和抹茶慕斯是同一产品族(也就是都属于美式风味)。

所以这个案例可以使用抽象工厂模式实现。类图如下:

二、代码实现

1)抽象产品及具体产品:

第一种产品:

Coffee(第一种抽象产品类)、AmericanCoffee和LatteCoffee (具体产品类)

代码语言:javascript
复制
public abstract class Coffee {
    public abstract void addMilk();
    public abstract void addSugar();
    public abstract String getName();
}
代码语言:javascript
复制
public class AmericanCoffee extends Coffee {
    @Override
    public void addMilk() {  System.out.println("给咖啡加奶");  }

    @Override
    public void addSugar() {  System.out.println("给咖啡加糖"); }

    @Override
    public String getName() {  return "美式咖啡"; }
}
代码语言:javascript
复制
public class LatteCoffee extends Coffee {
    @Override
    public void addMilk() {    System.out.println("给咖啡加奶"); }

    @Override
    public void addSugar() {  System.out.println("给咖啡加糖"); }

    @Override
    public String getName() {  return "拿铁咖啡"; }
}

第二种产品:

Dessert (第二种抽象产品 甜点) MatchaMousse、Tiramisu(具体产品类)

代码语言:javascript
复制
public abstract class Dessert {
    public abstract void show();
}
代码语言:javascript
复制
public class MatchaMousse extends Dessert{
    @Override
    public void show() {  System.out.println("抹茶慕斯"); }
}
代码语言:javascript
复制
public class Tiramisu extends Dessert{
    @Override
    public void show() {    System.out.println("提拉米苏"); }
}

2)抽象工厂 及具体工厂

DessertFactory (抽象工厂) AmericanDessertFactory 和(具体工厂)

代码语言:javascript
复制
public interface DessertFactory {

    Coffee createCoffee();

    Dessert createDessert();
}
代码语言:javascript
复制
public class AmericanDessertFactory implements DessertFactory {

    @Override
    public Coffee createCoffee() {   return new AmericanCoffee(); }

    @Override
    public Dessert createDessert() {  return new MatchaMousse(); }
}
代码语言:javascript
复制
public class ItalyDessertFactory implements DessertFactory {

    @Override
    public Coffee createCoffee() {   return new LatteCoffee(); }

    @Override
    public Dessert createDessert() {    return new Tiramisu(); }
}

3)测试

代码语言:javascript
复制
public class Client {
    public static void main(String[] args) {
         // 想次美式东西
	    // AmericanDessertFactory factory = new AmericanDessertFactory();
        // 想换成意大利风味,仅仅只需要换一个工厂类 其他的代码无需改变
        ItalyDessertFactory factory= new ItalyDessertFactory();
        Coffee coffee = factory.createCoffee();
        Dessert dessert = factory.createDessert();
        System.out.println(coffee.getName());
        dessert.show();
    }
}

如果要加同一个产品族的话,只需要再加一个对应的工厂类即可,不需要修改其他的类。

4)优缺点:

抽象工厂模式除了具有工厂方法模式的优点外,其他主要优点如下。

  • 可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。
  • 当需要产品族时,抽象工厂可以保证客户端始终只使用同一个产品的产品组。
  • 抽象工厂增强了程序的可扩展性,当增加一个新的产品族时,不需要修改原代码,满足开闭原则。

其缺点是:当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。增加了系统的抽象性和理解难度。

使用抽象工厂模式一般要满足以下条件。

  • 系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品。
  • 系统一次只可能消费其中某一族产品,即同族的产品一起使用。

5)使用场景:

如:输入法换皮肤,一整套一起换。生成不同操作系统的程序。

三、自言自语

我也不知道文章写出来是有用还是无用,只是想做一个分享。希望大家能够喜欢并且在这里能有收获。

你好啊,要天天开心哦。下篇文章再见。

此系列还在持续更新中… 我一定还会回来的。😁

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-09-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Java设计模式-工厂模式(3)抽象工厂模式
  • 一、前言
    • 1)概述:
      • 2)角色概述:
        • 3)前文
        • 二、代码实现
          • 1)抽象产品及具体产品:
            • 2)抽象工厂 及具体工厂
              • 3)测试
                • 4)优缺点:
                  • 5)使用场景:
                  • 三、自言自语
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档