当前位置: 首页 > article >正文

java 设计模式 工厂模式

什么是工厂模式

工厂模式(Factory Pattern)是一种创建型设计模式,它通过定义一个接口或抽象类来创建对象,但由子类决定具体实例化哪个类。简单来说,工厂模式将对象的实例化过程封装起来,客户端通过工厂方法来创建对象,而不需要直接使用 new 关键字。

工厂模式的目的是将对象的创建和使用解耦,使得客户端代码不需要关心具体对象的创建过程,尤其是对象的构造方式或者具体类型。

工厂模式的作用

  1. 解耦:客户端代码与具体的对象创建解耦,客户端只需要依赖工厂接口而不依赖具体的实现类。
  2. 代码重用:工厂方法可以提供统一的创建对象的逻辑,从而避免重复代码。
  3. 更好的扩展性:如果系统中需要新增不同的产品类,只需要添加新的工厂类即可,不需要修改原有的客户端代码。
  4. 灵活的对象管理:有些工厂模式可以实现对象的缓存或对象池,从而优化性能。

示例

不使用工厂模式获取实例

// 抽象产品:Button(按钮)
interface Button {
    void render();
}

// 具体产品:WindowsButton(Windows 按钮)
class WindowsButton implements Button {
    @Override
    public void render() {
        System.out.println("Rendering a Windows Button");
    }
}

// 具体产品:MacButton(Mac 按钮)
class MacButton implements Button {
    @Override
    public void render() {
        System.out.println("Rendering a Mac Button");
    }
}

// 客户端代码:根据操作系统类型选择不同按钮
public class Main {
    public static void main(String[] args) {
        Button button;
        String osType = "Windows";  // 假设从配置中获取操作系统类型

        if ("Windows".equalsIgnoreCase(osType)) {
            button = new WindowsButton();
        } else {
            button = new MacButton();
        }

        button.render();
    }
}

这里如果又新增一个liunx按钮 客户端又要重新修改代码

使用工厂模式

// 抽象产品:Button(按钮)
interface Button {
    void render();
}

// 具体产品:WindowsButton(Windows 按钮)
class WindowsButton implements Button {
    @Override
    public void render() {
        System.out.println("Rendering a Windows Button");
    }
}

// 具体产品:MacButton(Mac 按钮)
class MacButton implements Button {
    @Override
    public void render() {
        System.out.println("Rendering a Mac Button");
    }
}

// 具体产品:LinuxButton(Linux 按钮)
class LinuxButton implements Button {
    @Override
    public void render() {
        System.out.println("Rendering a Linux Button");
    }
}

// 抽象工厂:GUIFactory
interface GUIFactory {
    Button createButton();
}

// 具体工厂:WindowsFactory
class WindowsFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new WindowsButton();
    }
}

// 具体工厂:MacFactory
class MacFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new MacButton();
    }
}

// 具体工厂:LinuxFactory
class LinuxFactory implements GUIFactory {
    @Override
    public Button createButton() {
        return new LinuxButton();
    }
}

// 工厂创建器:根据操作系统类型选择对应的工厂
class FactoryCreator {
    public static GUIFactory getFactory(String osType) {
        if ("Windows".equalsIgnoreCase(osType)) {
            return new WindowsFactory();
        } else if ("Mac".equalsIgnoreCase(osType)) {
            return new MacFactory();
        } else if ("Linux".equalsIgnoreCase(osType)) {
            return new LinuxFactory();
        }
        return null;
    }
}

// 客户端代码:通过工厂创建按钮
public class Main {
    public static void main(String[] args) {
        // 假设从配置文件或环境变量获取操作系统类型
        String osType = System.getProperty("os.name"); // 获取操作系统名称(例如:Windows、Mac、Linux)

        // 使用工厂创建器自动选择工厂
        GUIFactory factory = FactoryCreator.getFactory(osType);
        
        // 通过工厂创建按钮
        if (factory != null) {
            Button button = factory.createButton();
            button.render();
        } else {
            System.out.println("No suitable factory found for " + osType);
        }
    }
}

这里你无论新增多少按钮,客户端代码始终不变

工厂模式的种类

简单工厂模式(Simple Factory Pattern)

通过一个工厂类来根据参数的不同返回不同类型的对象。
优点:客户端代码很简单,所有的产品类都集中在一个地方。
缺点:如果产品类增多,工厂类需要做出改动,违反了开放-封闭原则。

示例

产品类

class Car {
    void drive() {
        System.out.println("Driving a car");
    }
}

class Truck {
    void drive() {
        System.out.println("Driving a truck");
    }
}



工厂类

class VehicleFactory {
    public static Object createVehicle(String type) {
        if (type.equals("car")) {
            return new Car();
        } else if (type.equals("truck")) {
            return new Truck();
        }
        return null;
    }
}


public class Main {
    public static void main(String[] args) {
        Object vehicle = VehicleFactory.createVehicle("car");
        if (vehicle instanceof Car) {
            ((Car) vehicle).drive();
        }
    }
}

工厂方法模式(Factory Method Pattern)

定义一个创建对象的接口,但让子类决定实例化哪个类。这样,工厂方法模式允许子类来决定返回什么样的对象,而不需要修改客户端代码。
优点:符合开放-封闭原则,产品扩展时不需要修改客户端代码。

简单来说,就是有个产品,咱们需要定义一个接口或者抽象类定义需要实现的方法(例如开车),然后创建多个具体类实现或者继承该方法去实现不同的开车类型(开卡车,开拖拉机,开小车),有了具体的类之后,需要创建工厂帮我们创建开车类型,这里比简单工厂模式优化点是,创建一了一个抽象工厂,让下面的子类具体工厂继承抽象工厂来帮我们实现具体的产品。这样符合开闭原则了

产品类

interface Vehicle {
    void drive();
}

class Car implements Vehicle {
    @Override
    public void drive() {
        System.out.println("Driving a car");
    }
}

class Truck implements Vehicle {
    @Override
    public void drive() {
        System.out.println("Driving a truck");
    }
}


工厂类

abstract class VehicleFactory {
    abstract Vehicle createVehicle();
}

class CarFactory extends VehicleFactory {
    @Override
    Vehicle createVehicle() {
        return new Car();
    }
}

class TruckFactory extends VehicleFactory {
    @Override
    Vehicle createVehicle() {
        return new Truck();
    }
}


public class Main {
    public static void main(String[] args) {
        VehicleFactory factory = new CarFactory();
        Vehicle vehicle = factory.createVehicle();
        vehicle.drive();
    }
}

抽象工厂模式

提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们具体的类。
工厂方法模式创建的是单个对象,而抽象工厂模式创建的是多个相关对象。

简单来说抽象工厂就是有几个配套的抽象产品(车轮和车胎),多个具体的类实现不同的抽象产品(车轮和车胎)当成具体实现类(越野车胎,越野车轮,公路车胎,公路车轮),有了这些类之后,需要实现工厂来帮我们进行组合,所有有个抽象工厂类用来创建车胎和车轮,然后创建具体的工厂实现抽象工厂,来返回配套的车胎车轮。

示例

产品类

// 抽象产品:车轮
interface Wheel {
    void create();
}

// 抽象产品:轮胎
interface Tire {
    void create();
}

// 具体产品:越野车轮
class OffRoadWheel implements Wheel {
    @Override
    public void create() {
        System.out.println("Creating Off-road Wheel");
    }
}

// 具体产品:公路车轮
class RoadWheel implements Wheel {
    @Override
    public void create() {
        System.out.println("Creating Road Wheel");
    }
}

// 具体产品:越野轮胎
class OffRoadTire implements Tire {
    @Override
    public void create() {
        System.out.println("Creating Off-road Tire");
    }
}

// 具体产品:公路轮胎
class RoadTire implements Tire {
    @Override
    public void create() {
        System.out.println("Creating Road Tire");
    }
}

工厂类

// 抽象工厂:车轮和轮胎的工厂
interface VehiclePartsFactory {
    Wheel createWheel();
    Tire createTire();
}

// 具体工厂:越野车配件工厂
class OffRoadVehiclePartsFactory implements VehiclePartsFactory {
    @Override
    public Wheel createWheel() {
        return new OffRoadWheel();
    }

    @Override
    public Tire createTire() {
        return new OffRoadTire();
    }
}

// 具体工厂:公路车配件工厂
class RoadVehiclePartsFactory implements VehiclePartsFactory {
    @Override
    public Wheel createWheel() {
        return new RoadWheel();
    }

    @Override
    public Tire createTire() {
        return new RoadTire();
    }
}


// 客户端代码
public class Main {
    public static void main(String[] args) {
        // 创建越野车配件工厂
        VehiclePartsFactory offRoadFactory = new OffRoadVehiclePartsFactory();
        Wheel offRoadWheel = offRoadFactory.createWheel();
        Tire offRoadTire = offRoadFactory.createTire();
        offRoadWheel.create();
        offRoadTire.create();

        // 创建公路车配件工厂
        VehiclePartsFactory roadFactory = new RoadVehiclePartsFactory();
        Wheel roadWheel = roadFactory.createWheel();
        Tire roadTire = roadFactory.createTire();
        roadWheel.create();
        roadTire.create();
    }
}

springboot哪些地方使用了工厂模式

BeanFactory 和 ApplicationContext

Spring 提供了 BeanFactory 和 ApplicationContext 作为工厂类来管理 bean 的创建和生命周期。这两个接口实际上是工厂模式的应用,ApplicationContext 扩展了 BeanFactory,用于创建和管理应用程序中的 bean。

示例

@Configuration
public class AppConfig {
    @Bean
    public Car car() {
        return new Car();
    }
}

@SpringBootApplication
public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        Car car = context.getBean(Car.class);
        car.drive();
    }
}

FactoryBean

FactoryBean 是一个工厂类,但是它并不是直接返回一个简单的对象,而是返回一个由 FactoryBean 实现逻辑控制的复杂对象。

示例

这里可以对比之前的工厂模式,可以看出就是工厂模式(有产品类,有工厂类,有具体工厂实现)

public class Car {
    public void drive() {
        System.out.println("Driving the car!");
    }
}

public class CarFactoryBean implements FactoryBean<Car> {

    @Override
    public Car getObject() throws Exception {
        // 在这里可以写复杂的创建逻辑
        System.out.println("Creating Car object via FactoryBean");
        return new Car();
    }

    @Override
    public Class<?> getObjectType() {
        return Car.class;
    }

    @Override
    public boolean isSingleton() {
        return true;  // 返回单例
    }
}

JdbcTemplate

JdbcTemplate 是 Spring 中的一个工具类,它通过工厂模式封装了数据库连接的创建过程,并提供了统一的操作接口。开发者无需关心底层数据库连接的具体实现。

何时使用工厂模式?

需要隐藏对象创建的复杂性 当对象的创建过程复杂时,直接使用 new 关键字可能会导致代码重复、易出错、难以维护。通过工厂模式,可以将对象创建的过程封装到工厂类中,客户端代码不需要关心如何创建对象,而只需要关心如何使用对象。

需要创建的对象有多个子类 当你需要创建的对象有多个具体实现类,而这些类的具体实现对客户端不重要时,可以通过工厂模式来集中管理这些不同的对象创建过程。工厂模式能够根据不同的参数或条件动态决定实例化哪个具体的类。

对象的创建过程可能会变化或扩展 当系统需要支持未来扩展(例如,新增产品类或功能)时,使用工厂模式可以避免修改已有代码,只需要扩展工厂类来支持新的对象创建。工厂模式遵循 开放-封闭原则,便于扩展而不需要修改现有的客户端代码。

需要依赖注入和对象管理 在一些框架(如 Spring)中,工厂模式用于创建和管理对象,例如 BeanFactory 和 ApplicationContext 就是通过工厂模式来管理对象的生命周期和依赖关系。

简单来说


http://www.kler.cn/a/505767.html

相关文章:

  • Freeswitch使用media_bug能力实现回铃音检测
  • Spring AI 从入门到实践
  • 探索 Vue.js 组件开发的新边界:动态表单生成技术
  • 全网首发:编译libssh,产生类似undefined reference to `EVP_aes_256_ctr@OPENSSL_1_1_0‘的大量错误
  • Flutter:封装ActionSheet 操作菜单
  • 【Node.js的安装与配置】
  • JavaScript前端高效性能优化策略:防抖和节流的详细介绍
  • 【JavaWeb】JavaWeb入门之Tomcat详解
  • CNCF云原生计算基金会
  • Yolo 对象检测系列更新无止境,Ultralytics 发布 Yolov11 更快,更强
  • 0115java面经
  • 【Rust自学】12.7. 使用环境变量
  • SpringBoot开发——Spring Boot 自动化测试框架的高效运用
  • Java并发编程——线程池(基础,使用,拒绝策略,命名,提交方式,状态)
  • Mybatis-底层是如何解决sql注入增删改查操作--删除操作
  • VUE请求返回二进制文件流下载文件例子
  • doc、pdf转markdown
  • STM32H7通过CUBEMX初始化移植LWIP,DHCP建立RAW TCP服务器,不停发成功
  • Spring MVC复杂数据绑定-绑定集合
  • VUE3 + Ant Design Vue4 开发笔记
  • MySQL表的增删改查(进阶)-下篇
  • 【Qt】QThread总结
  • flutter R库对图片资源进行自动管理
  • c#删除文件和目录到回收站
  • 【Linux系统编程】—— 自动化构建工具Makefile指南
  • rtthread学习笔记系列(3) -- FINSH模块