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笔记

相关推荐
brave_zhao8 分钟前
launch4j亲测打包java的jar转为exe执行文件
java
利刃大大9 分钟前
【RabbitMQ】SpringBoot整合RabbitMQ:工作队列 && 发布/订阅模式 && 路由模式 && 通配符模式
java·spring boot·消息队列·rabbitmq·java-rabbitmq
lkbhua莱克瓦2410 分钟前
进阶-存储对象1-视图
java·数据库·sql·mysql·视图
yangminlei12 分钟前
Spring Boot 自动配置原理与自定义 Starter 开发实战
java·数据库·spring boot
悟空码字14 分钟前
10分钟搞定!SpringBoot集成腾讯云短信全攻略,从配置到发送一气呵成
java·spring boot·后端
爱编程的小吴16 分钟前
【力扣练习题】151. 反转字符串中的单词
java·算法·leetcode
未来龙皇小蓝24 分钟前
Spring注入Bean流程及其理解
java·spring boot·后端·spring·代理模式
知秋正在99628 分钟前
Java实现Html保存为.mhtml文件
java·开发语言·html
码头整点薯条31 分钟前
大数据量查询处理方案
java
菜鸟233号33 分钟前
力扣474 一和零 java实现
java·数据结构·算法·leetcode·动态规划