初学 Java 设计模式(三):实战抽象工厂方法模式 「QQ 厘米秀装扮」

一、抽象工厂方法模式介绍

1. 解决的问题

通过接口的选择,解决在系统产品存在多个产品族,而系统仅消费某一族的产品的问题。

2. 定义

抽象工厂模式是一个围绕超级工厂创建其他工厂的模式,即抽象工厂是一个中心工厂,创建其他工厂的模式。

抽象工厂提供了一个接口,可用于创建每个系列产品的对象。只要代码通过该接口创建对象,那么就不会生产与当前系统已生成的产品类型不一致的产品。

二、抽象工厂方法模式优缺点

1. 优点

  • 可以确保同一工厂生产的产品相互匹配。
  • 可以避免客户端和具体产品代码的耦合。
  • 单一职责原则:将产品生成代码抽取到同一位置,使得产品代码易于维护。
  • 开闭原则:向应用程序引入新产品变体时,无需修改客户端代码。

2. 缺点

  • 由于采用该模式需要向应用中引入众多接口和类,代码可能会比之前更加复杂。

三、抽象工厂方法模式应用实例:QQ 厘米秀装扮

1. 实例场景

QQ 陪伴我们了 22 年,从 QQ 秀到厘米秀,二维图片到三维立体个人秀,接下来我们以厘米秀的各种装扮作为模拟场景。

以厘米秀的两种套装风格作为示例:

  • 现代风:帽子、西装、西裤、皮鞋
  • 复古风:礼帽、大衣、长裤、长靴

2. 抽象工厂方法模式实现

2.1 工程结构
abstract-factory-pattern
└─ src
    ├─ main
    │    └─ java
    │    └─ org.design.pattern.abstract_factory
    │       ├─ model
    │       │  └─ hat
    │       │  │    ├─ Hat.java
    │       │  │    ├─ ModernHat.java
    │       │  │    └─ RetroHat.java
    │       │  └─ coat
    │       │  │    ├─ Coat.java
    │       │  │    ├─ ModernCoat.java
    │       │  │    └─ RetroCoat.java
    │       │  └─ pants
    │       │  │    ├─ Pants.java
    │       │  │    ├─ ModernPants.java
    │       │  │    └─ RetroPants.java
    │       │  └─ shoes
    │       │          ├─ Shoes.java
    │       │          ├─ ModernShoes.java
    │       │          └─ RetroShoes.java
    │       ├─ factory
    │       │    ├─ SuitFactory.java
    │       │    ├─ ModernSuitFactory.java
    │       │    └─ RetroSuitFactory.java
    │       |           
    │       └─ service
    │           ├─ CmShowService.java
    │           └─ CmShowServiceImpl.java
    └─ test
        └─ java
            └─ org.design.pattern.abstract_factory.test
                  └─ CmShowServiceTest.java
2.2 代码实现
2.2.1 基础服饰

帽子

/**
 * 帽子
 */
public interface Hat {
    void getStyle();
}

现代风帽子

/**
 * 现代风帽子
 */
public class ModernHat implements Hat {
    @Override
    public void getStyle() {
        System.out.println("现代风帽子");
    }
}

复古风帽子

/**
 * 复古风帽子
 */
public class RetroHat implements Hat {
    @Override
    public void getStyle() {
        System.out.println("复古风礼帽");
    }
}
2.2.2 装扮套装工厂类

套装工厂

/**
 * 套装工厂
 */
public interface SuitFactory {
    Hat createHat();
    Coat createCoat();
    Pants createPants();
    Shoes createShoes();
}

现代风套装工厂

/**
 * 现代风套装工厂
 */
public class ModernSuitFactory implements SuitFactory {
    @Override
    public Hat createHat() {
        return new ModernHat();
    }

    @Override
    public Coat createCoat() {
        return new ModernCoat();
    }

    @Override
    public Pants createPants() {
        return new ModerPants();
    }

    @Override
    public Shoes createShoes() {
        return new ModernShoes();
    }
}

复古风套装工厂

/**
 * 复古风套装工厂
 */
public class RetroSuitFactory implements SuitFactory {
    @Override
    public Hat createHat() {
        return new RetroHat();
    }

    @Override
    public Coat createCoat() {
        return new RetroCoat();
    }

    @Override
    public Pants createPants() {
        return new RetroPants();
    }

    @Override
    public Shoes createShoes() {
        return new RetroShoes();
    }
}
2.3 测试验证
2.3.1 编写测试类
public class CmShowServiceTest {
    @Test
    public void getModernSuitCmShow() {
        SuitFactory suitFactory = new ModernSuitFactory();
        CmShowService cmShowService = new CmShowServiceImpl(suitFactory);
        cmShowService.getSuitStyle();
    }

    @Test
    public void getRetroSuitCmShow() {
        SuitFactory suitFactory = new RetroSuitFactory();
        CmShowService cmShowService = new CmShowServiceImpl(suitFactory);
        cmShowService.getSuitStyle();
    }
}
2.3.2 测试结果
现代风厘米秀:
现代风帽子
现代风西装
现代风西裤
现代风鞋子
复古风厘米秀:
复古风礼帽
复古风大衣
复古风长裤
复古风长靴

四、抽象工厂方法模式结构

抽象工厂模式结构图

  1. 抽象产品 (Abstract Product) 为构成系列产品的一组不同但相关的产品声明接口。
  2. 具体产品 (Concrete Product) 是抽象产品的多种不同类型实现。 所有变体 ( 现代风/复古风) 都必须实现相应的抽象产品 (帽子/上衣)。
  3. 抽象工厂 (Abstract Factory) 接口声明了一组创建各种抽象产品的方法。
  4. 具体工厂 (Concrete Factory) 实现抽象工厂的构建方法。 每个具体工厂都对应特定产品变体, 且仅创建此种产品变体。
  5. 尽管具体工厂会对具体产品进行初始化, 其构建方法签名必须返回相应的抽象产品。 这样, 使用工厂类的客户端代码就不会与工厂创建的特定产品变体耦合。 服务 (Service) 只需通过抽象接口调用工厂和产品对象, 就能与任何具体工厂/产品变体交互。

设计模式并不难学,其本身就是多年经验提炼出的开发指导思想,关键在于多加练习,带着使用设计模式的思想区优化代码,就能构建出更合理的代码。

源码地址: https://github.com/yiyufxst/d...

参考资料:
小博哥重学设计模式:https://github.com/fuzhengwei...
深入设计模式:https://refactoringguru.cn/de...

你可能感兴趣的:(java设计模式抽象工厂模式)