Java设计模式 | 工厂方法模式

工厂方法模式

针对简单工厂模式案例中的缺点,使用工厂方法模式就可以完美的解决,完全遵循开闭原则。

简单工厂模式只有一个工厂类,负责创建所有产品,如果要添加新的产品,就需要修改工厂类的代码。而工厂方法模式引入了抽象工厂和具体工厂的概念,每个具体工厂只负责创建一种具体的产品,添加新产品只需要添加新的工厂而无需修改原来的代码。这样使得产品的生产更灵活,扩展性更强,符合开闭原则。

结构

工厂方法模式分为以下几个角色:

  • 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法来创建产品
  • 具体工厂(Concrete Factory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建
  • 抽象产品(Abstract Product):定义了产品的规范,描述了产品的主要特性和功能
  • 具体产品 (Abstract Product):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应
实现

抽象咖啡工厂:

java 复制代码
public interface CoffeeFactory {

    // 创建咖啡对象的方法
    Coffee createCoffee();
}

美式咖啡工厂:

java 复制代码
public class AmericanCoffeeFactory implements CoffeeFactory {
    @Override
    public Coffee createCoffee() {
        return new AmericanCoffee();
    }
}

拿铁咖啡工厂:

java 复制代码
public class LatteCoffeeFactory implements CoffeeFactory {
    @Override
    public Coffee createCoffee() {
        return new LatteCoffee();
    }
}

咖啡类:

java 复制代码
public abstract class Coffee {

    // 获取咖啡名
    public abstract String getName();

    // 加糖
    public void addSugar(){
        System.out.println("加糖");
    }

    // 加奶
    public void addMilk(){
        System.out.println("加奶");
    }
}

美式咖啡类:

java 复制代码
public class AmericanCoffee extends Coffee {
    @Override
    public String getName() {
        return "美式咖啡";
    }
}

拿铁咖啡类:

java 复制代码
public class LatteCoffee extends Coffee {
    @Override
    public String getName() {
        return "拿铁咖啡";
    }
}

咖啡店类:

java 复制代码
public class CoffeeStore {

    private CoffeeFactory coffeeFactory;

    public void setCoffeeFactory(CoffeeFactory coffeeFactory) {
        this.coffeeFactory = coffeeFactory;
    }

    // 点咖啡
    public Coffee orderCoffee(String type) {
        Coffee coffee = coffeeFactory.createCoffee();
        coffee.addMilk();
        coffee.addSugar();
        return coffee;
    }
}

测试:

java 复制代码
public class Client {
    public static void main(String[] args) {
        // 创建对象
        CoffeeStore coffeeStore = new CoffeeStore();
        // 拿铁咖啡美式咖啡
//        CoffeeFactory coffeeFactory = new AmericanCoffeeFactory();
        // 拿铁咖啡
        CoffeeFactory coffeeFactory = new LatteCoffeeFactory();
        coffeeStore.setCoffeeFactory(coffeeFactory);

        // 点咖啡
        Coffee coffee = coffeeStore.orderCoffee("Latte");
        System.out.println(coffee.getName());
    }
}
总结

可以看出,要增加产品类时也要相应的增加工厂类,不需要修改工厂类的代码,这样就解决了简单工厂模式的缺点(违反开闭原则)。

工厂方法模式是简单工厂模式的进一步抽象,由于使用了多态性,工厂方法模式保持了简单工厂模式的优点,并且解决了它的缺点。
优点:

  • 用户只需要知道具体工厂的名称就可得到需要的产品,不管产品的具体创建过程
  • 在系统增加新产品时只需要添加具体的产品类和对应的工厂类,无需对原工厂进行任何修改,符合开闭原则

缺点:

  • 每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,增加了系统复杂度
应用场景

工厂方法模式使得每个工厂类的职责单一,每个工厂只负责创建一种产品,当创建对象涉及一系列复杂的初始化逻辑,而这些逻辑在不同的子类中可能有所不同时,可以使用工厂方法模式将这些初始化逻辑封装在子类中。如:

  • Spring框架中的Bean工厂:通过配置文件或者注解,Spring可以根据配置文件动态的创建和管理对象
  • JDBC中的Connection工厂:在Java数据库连接中,DriverManager使用工厂方法模式来创建数据库连接。不同的驱动(MySQL,Oracle等)都有对应的工厂来创建连接

github笔记

相关推荐
禅思院1 小时前
前端请求取消与调度完全指南:从 AbortController 到企业级优先级架构
前端·设计模式·前端框架
lulu12165440781 小时前
大模型API聚合平台技术架构深度对比:六大平台协议转换、路由调度与安全治理全解析 - 微元算力(weytoken)
java·人工智能·安全·架构·ai编程
可乐ea1 小时前
【Spring Boot + MyBatis|第4篇】MyBatis 动态 SQL:if、where、foreach 使用详解
java·spring boot·后端·sql·mybatis
記億揺晃着的那天1 小时前
Windows 通过 Java 获取可用端口的一个坑:Hyper-V 保留端口导致 UDP 绑定失败
java·windows·udp
组合缺一1 小时前
SolonCode(编码智能体)支持鸿蒙 PC
java·华为·ai·ai编程·harmonyos·solon·soloncode
小bo波1 小时前
用匿名内部类优雅地计算方法执行时间
java·设计模式·性能测试·模板方法模式·lambda·代码优化·匿名内部类
折哥的程序人生 · 物流技术专研1 小时前
Tomcat 严重警告:JDBC 驱动未注销 + 工作线程泄漏 —— 原因、影响与彻底修复(生产级终极指南)
java·运维·数据库·mysql·oracle·tomcat
一个儒雅随和的男子2 小时前
sentinel底层原理剖析以及实战优化
java·网络·sentinel
两年半的个人练习生^_^2 小时前
JMM 进阶:彻底理解 synchronized 实现原理
java·开发语言
戳代码的新星2 小时前
论小白如何学会使用Maven
java·maven