设计模式 - 工厂模式 精准梳理&精准记忆

发布于:2025-03-10 ⋅ 阅读:(13) ⋅ 点赞:(0)

在这里插入图片描述

在这里插入图片描述

                                                         1、代码片段 - 带入理解


一、核心模式分类

  1. 简单工厂模式(编程习惯,非 GoF 设计模式)
  2. 工厂方法模式(GoF 创建型模式)
  3. 抽象工厂模式(GoF 创建型模式)


二、演变过程:咖啡店案例

初始实现

// 咖啡基类
abstract class Coffee {
     public abstract String getName();
}

class AmericanCoffee extends Coffee {}
class LatteCoffee extends Coffee {}

// 咖啡店直接创建对象
class CoffeeStore {
     public Coffee orderCoffee(String type) {
          if ("american".equals(type)) {
               return new AmericanCoffee();
          } else {
               return new LatteCoffee();
          }
     }
}

问题   违反开闭原则,新增咖啡类型需修改订单方法



三、改进方案演变

1、简单工厂模式

class SimpleCoffeeFactory {
    public Coffee createCoffee(String type) {
        // 创建逻辑...
    }
}

class CoffeeStore {
    private SimpleCoffeeFactory factory;
    public Coffee orderCoffee(String type) {
        return factory.createCoffee(type);
    }
}
  • 优点   解耦对象创建
  • 缺点  仍需修改工厂代码,违反开闭原则

2、工厂方法模式

interface CoffeeFactory {
    Coffee createCoffee();
}

class AmericanFactory implements CoffeeFactory {
    public Coffee createCoffee() { return new AmericanCoffee(); }
}

class CoffeeStore {
    private CoffeeFactory factory;
    public void setFactory(CoffeeFactory factory) {
        this.factory = factory;
    }
    public Coffee orderCoffee() {
        return factory.createCoffee();
    }
}
  • 优点   完全遵循开闭原则
  • 缺点   类数量激增(类爆炸问题)

3、抽象工厂模式

interface DessertFactory {
    Coffee createCoffee();
    Dessert createDessert();
}

class AmericanDessertFactory implements DessertFactory {
    public Coffee createCoffee() { return new AmericanCoffee(); }
    public Dessert createDessert() { return new MatchaMousse(); }
}
  • 优点   管理产品族(咖啡+甜点的组合)
  • 代价   新增产品类型需修改所有工厂接口

4、模式对比表

模式特性 简单工厂 工厂方法 抽象工厂
扩展性 修改工厂类 新增工厂子类 新增工厂实现类
产品维度 单一产品 单一产品 产品族(多相关产品)
开闭原则 违反 遵循 部分遵循
复杂度
典型应用场景 简单对象创建 需要灵活扩展的产品创建 系列关联产品的组合创建


四、进阶应用技巧

1、静态工厂

class SimpleCoffeeFactory {
     public static Coffee createCoffee(String type) {
          // 创建逻辑...
     }
}

2、配置化工厂

# bean.properties
american=com.example.AmericanCoffee
latte=com.example.LatteCoffee
class ConfigFactory {
     private static Map<String, Coffee> cache = new HashMap<>();

     static {
          // 加载配置文件,反射创建对象存入缓存
     }

     public static Coffee getCoffee(String key) {
          return cache.get(key);
     }
}

全部代码

public class CoffeeFactory {
     // 加载配置文件, 获取配置文件中配置的全类名, 并创建该类的对象进行存储
     // 1.定义容器对象用来存储咖啡对象
     private static HashMap<String, Coffee> map = new HashMap<String, Coffee>();

     // 2.加载配置文件, 只需要加载一次
     static {
          // 2.1 创建proper.ties 对象
          Properties p = new Properties();
          // 2.2调用p对象中的load 方法进行配置文件的加载   获取字节码 -> 获取类加载器 -> 获取目标资源(返回inputStream)
          InputStream is = CoffeeFactory.class.getClassLoader().getResourceAsStream("bean.properties");
          try {
               // 加载资源
               p.load(is);
               // 从p集合中获取全类名并创建对象
               Set<Object> keys = p.keySet();
               for (Object key : keys) {
                    String className = p.getProperty((String) key);
                    // 通过反射创建对象
                    Class<?> clazz = Class.forName(className);
                    Coffee coffee = (Coffee) clazz.newInstance();// 创建对象
                    // 将名称和对象存储到容器中
                    map.put((String) key,coffee);
               }
          } catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException e) {
               e.printStackTrace();
          }
     }

     // 根据名称获取对象
     public static Coffee createCoffee(String name){
          return map.get(name);
     }
}


五、JDK典型案例

  1. 集合迭代器
// 工厂方法模式应用
Collection<String> coll = new ArrayList<>();
Iterator<String> it = coll.iterator(); // ArrayList内部实现Iterator
  1. 日期工具
Calendar cal = Calendar.getInstance(); // 根据时区返回不同实现
DateFormat df = DateFormat.getInstance();




                                                         2、文字提炼 - 记忆切入点


一、简单工厂模式

1、核心思想

将对象创建逻辑集中在一个"工厂类"中,通过 参数 控制具体产品类型。

  • 关键步骤

    1. 定义产品接口
      创建抽象基类(如 Coffee),声明所有产品共有的方法(如 getName()

    2. 实现具体产品
      继承基类创建具体产品(如 AmericanCoffeeLatteCoffee),各自实现特有逻辑

    3. 构建工厂类
      创建 SimpleCoffeeFactory 类,内部包含静态/实例方法(如 createCoffee(type)),通过 if-elseswitch 判断参数类型,返回对应的具体产品实例

    4. 客户端调用
      客户端(如CoffeeStore)持有工厂引用,调用createCoffee()时传入类型参数,无需直接接触具体产品类

  • 典型特征

    • 工厂类包含所有产品的创建逻辑

    • 新增产品必须修改工厂类代码



二、工厂方法模式

2、核心思想

将对象的创建 延迟 到子类,每个产品对应一个专属工厂。

  • 关键步骤

    1. 定义抽象工厂接口
      创建CoffeeFactory接口,声明抽象方法(如createCoffee()

    2. 实现具体工厂
      为每个产品创建专属工厂类(如AmericanCoffeeFactoryLatteCoffeeFactory),在createCoffee()中返回对应的具体产品实例

    3. 客户端依赖抽象
      客户端类(如CoffeeStore)持有工厂接口的引用,通过setFactory()方法注入具体工厂

    4. 动态创建产品
      客户端调用factory.createCoffee()时,实际执行的是具体工厂类中实现的创建逻辑

  • 典型特征

    • 每个产品对应一个独立工厂类

    • 新增产品只需添加新工厂,无需修改已有代码



三、抽象工厂模式

2、核心思想

创建相关产品族的工厂,保证产品之间的兼容性。

  • 关键步骤

    1. 定义产品族接口
      创建多个抽象产品接口(如 Coffee: 咖啡Dessert: 甜点),每个接口代表一类产品

    2. 定义抽象工厂接口
      创建DessertFactory: 甜点工厂接口,声明创建系列产品的方法(如 createCoffee()createDessert()

    3. 实现具体工厂
      为每个产品族创建工厂类(如AmericanDessertFactory: 美式甜点工厂),同时实现该族内 所有产品的创建逻辑

    4. 客户端组合使用
      客户端通过选择具体工厂,获得配套的产品组合(如美式咖啡 + 抹茶慕斯),确保产品间的兼容性

  • 典型特征

    • 一个工厂创建多个关联产品

    • 新增产品类型时, 需要修改所有工厂接口



四、工厂模式历史演进

  1. 简单工厂   解决直接 new 对象带来的耦合问题,但工厂本身成为新的耦合点
  2. 工厂方法   通过多态工厂解耦,支持扩展但容易产生类爆炸
  3. 抽象工厂   应对产品组合需求,用更高维度的抽象管理关联对象


五、记忆点 - 关键区别

  • 考虑创建目标时

    • 简单工厂   单一产品
    • 工厂方法   单一产品
    • 抽象工厂   产品族

  • 考虑扩展代价时

    • 简单工厂   修改工厂类
    • 工厂方法   新增工厂类
    • 抽象工厂   修改所有工厂接口

  • 考虑设计重心时

    • 简单工厂   创建逻辑集中化
    • 工厂方法   创建责任分散化
    • 抽象工厂  产品组合约束



提炼

模式选择指南

  1. 简单工厂   适用于对象创建逻辑简单,不需要频繁扩展
  2. 工厂方法   适合需要灵活扩展产品类型的场景
  3. 抽象工厂   适用于管理产品族,强调相关产品必须配套使用

关键设计原则体现

  1. 开闭原则   工厂方法模式的典型体现
  2. 单一职责   每个工厂只负责创建特定对象
  3. 依赖倒置   客户端依赖抽象接口而非具体实现

如果这篇文章帮到你, 帮忙点个关注呗, 不想那那那点赞或收藏也行鸭 (。•̀ᴗ-)✧ ~

在这里插入图片描述

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述
                                                                                                                                   '(இ﹏இ`。)


网站公告

今日签到

点亮在社区的每一天
去签到