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

设计模式-创建型-工厂模式

设计模式-创建型-工厂模式

1.工厂模式概述

什么是工厂模式

工厂模式的应用将对象的创建和使用分离开,将创建对象的工厂用类方法封装。

工厂模式的作用

工厂模式将创建对象的具体工程屏蔽隔离起来。

  • 对象创建的具体过程有哪些:

    • 检查类是否已经加载,类加载仅在首次使用时触发(懒加载)

    • 内存分配,寻找内存可用块

    • 对象初始化,设置初始值

    • 生成的子对象实例,生成的辅助对象

  • 显式创建对象的几种方式(工厂方法除外)

    • 使用new关键字

    • 反射 Class.newInstance()Constructor.newInstance()

    • 对象克隆 clone()

    • 反序列化 ObjectInputStream.readObject()

工厂模式有几类

  • 简单工厂

  • 工厂方法

  • 抽象工厂

2. 各种创建对象方式的形象类比

1.1 没有工厂(直接 new 创建)

类比: 客户要自己购买宝马车的所有零件(发动机、轮胎、座椅等),然后手动组装成一辆车。

  • 过程:客户需要了解零件型号、组装流程,甚至需要专业工具。

  • 代码示例:

    BMWCar car = new BMWCar("X5", "Black", 3.0); // 直接实例化对象
  • 特点:

    • 简单直接:适合小规模、固定的对象创建。

    • 紧耦合:客户端必须知道具体类的细节(如类名、构造参数)。

    • 扩展困难:新增车型需修改客户端代码。


2.2 简单工厂(Simple Factory)

类比: 客户通过汽车订购中心(工厂)下单,只需告诉中心“我要一辆SUV”,工厂自动生产并交付。

  • 过程:工厂类根据参数(如车型)决定创建哪种具体对象。

  • 代码示例:

    public class CarFactory {public static Car createCar(String type) {if ("SUV".equals(type)) return new BMW_X5();if ("Sedan".equals(type)) return new BMW_3Series();return null;}
    }
    // 客户端
    Car car = CarFactory.createCar("SUV");
  • 特点:

    • 解耦:客户端无需知道具体类,只需依赖工厂。

    • 违反开闭原则:新增车型需修改工厂类(如添加 if 分支)。

    • 集中管理:适合产品种类少且稳定的场景(如配置化弹窗)。


2.3 工厂方法(Factory Method)

类比: 汽车品牌(如宝马、奔驰)各自成立独立工厂,客户选择品牌后,由该品牌的工厂生产车型。

  • 过程:抽象工厂定义创建方法,具体工厂子类实现生产逻辑。

  • 代码示例:

    // 抽象工厂
    public interface CarFactory {Car createCar();
    }
    // 具体工厂:宝马工厂
    public class BMWFactory implements CarFactory {@Overridepublic Car createCar() {return new BMW_X5();}
    }
    // 具体工厂:奔驰工厂
    public class MercedesFactory implements CarFactory {@Overridepublic Car createCar() {return new Mercedes_GLS();}
    }
    // 客户端
    CarFactory factory = new BMWFactory();
    Car car = factory.createCar();
  • 特点:

    • 开闭原则:新增品牌只需添加新工厂类,无需修改原有代码。

    • 职责单一:每个工厂只负责一种品牌。

    • 类数量增加:每新增一个产品需添加对应的工厂类。


2.4 抽象工厂(Abstract Factory)

类比: 汽车工厂不仅生产整车,还配套生产发动机、轮胎等,且同一品牌的产品风格统一(如宝马工厂生产宝马发动机+宝马轮胎)。

  • 过程:抽象工厂定义创建一组相关对象的方法,具体工厂实现整套产品的生产。

  • 代码示例:

    // 抽象产品:发动机
    public interface Engine { void start(); }
    // 具体产品:宝马发动机
    public class BMWEngine implements Engine {@Overridepublic void start() { System.out.println("宝马发动机启动"); }
    }
    // 抽象工厂:汽车工厂
    public interface CarFactory {Car createCar();Engine createEngine();
    }
    // 具体工厂:宝马工厂
    public class BMWFactory implements CarFactory {@Overridepublic Car createCar() { return new BMW_X5(); }@Overridepublic Engine createEngine() { return new BMWEngine(); }
    }
    // 客户端
    CarFactory factory = new BMWFactory();
    Car car = factory.createCar();
    Engine engine = factory.createEngine();
  • 特点:

    • 产品族一致性:确保配套产品兼容(如宝马车配宝马发动机)。

    • 扩展性强:新增品牌(如奥迪工厂)只需实现抽象工厂接口。

    • 复杂度高:需管理多个产品族的创建逻辑。


2.5 对比总结

方式核心思想适用场景优点缺点
无工厂直接实例化对象简单、临时的对象创建无需设计,快速实现紧耦合,难以扩展
简单工厂集中管理对象创建逻辑产品种类少且稳定解耦客户端与具体类新增产品需修改工厂类
工厂方法子类决定创建哪种产品需要灵活扩展产品类型符合开闭原则,职责单一类数量增加,结构复杂
抽象工厂创建一组相关的产品族需要配套产品且兼容性要求高保证产品族一致性,扩展性强实现复杂,需管理多层级关系

3.工厂模式的类图

根据笔记内容,以下是工厂模式的类图(使用Mermaid语法绘制):

3.1 没有工厂(直接new创建)

creates

Client

+main()

BMWCar

+BMWCar(model, color, engine)

  • 客户要自己购买车架、车漆、发动机

  • 客户要知道车的组装细节

优点:

  • 无需设计,快速实现简单、临时的对象创建。

缺点:

  • 紧耦合,难以扩展

  • 代码臃肿

3.2 简单工厂

creates

uses

CarFactory

+createCar(type: String)

«interface»

Car

BMW_X5

BMW_3Series

Client

+main()

  • 客户可通知工厂组装所有车辆

优点:

  • 实现对象的创建和使用分离

  • 通过配置文件修改具体产品

缺点:

  • 添加新产品要修改工厂类

  • 产品过多稳定性就差,扩展会导致性能变差

3.3 工厂方法

creates

creates

uses

«interface»

CarFactory

+createCar()

BMWFactory

+createCar()

MercedesFactory

+createCar()

«interface»

Car

BMW_X5

Mercedes_GLS

Client

+main()

  • 客户通知具体工厂组装对应的具体产品

优点:

  • 具体工厂创建具体产品,不用修改工厂类

  • 配置文件更换具体工厂

缺点:

  • 一个产品对应一个工厂,类的数量成倍增加

3.4 抽象工厂

creates

creates

uses

«interface»

CarFactory

+createCar()

+createEngine()

BMWFactory

+createCar()

+createEngine()

«interface»

Car

BMW_X5

«interface»

Engine

+start()

BMWEngine

+start()

Client

+main()

  • 客户通过品牌工厂生产对应的品牌产品

优点:

  • 一个工厂生产一组产品族产品

缺点:

  • 增加旧品牌的产品将不符合开闭原则。

应用场景:

  • 切换服务商:阿里云、腾讯云、华为云等。

  • 切换主题:深色模式/浅色模式、各种主题皮肤。

4.配置文件

工厂模式在运行期往往需要“动态决定”到底创建哪一个具体产品或具体工厂,而不是在源码里写死。 把“要创建什么”这一信息从代码里剥离出来,最轻量的做法就是使用 配置文件(Properties 或 XML)。

http://www.dtcms.com/a/314395.html

相关文章:

  • 阿里云与华为云产品的差异
  • RTSP/RTMP播放器超低延迟实战:无人机远控视觉链路的工程实践
  • 项目配置文件正确但是启动失败,报配置文件内容错误或中间件地址与实际不符
  • wpf Image 转 90 度
  • 深入浅出 RabbitMQ:工作队列实战(轮训策略VS公平策略)
  • ShowDoc与Docmost对比分析:开源文档管理工具的选择指南
  • 05 基于sklearn的机械学习-梯度下降(下)
  • 神经网络---非线性激活
  • Vue 响应式数据核心:ref 与 reactive 的本质区别
  • transformer与神经网络
  • CMakeLists.txt学习
  • C++ 中 initializer_list 类型推导
  • Exporters | 安装elasticsearch_exporter
  • Kali基础知识点【2】
  • 【论文阅读】ACE: Explaining cluster from an adversarial perspective
  • 【Java】HashMap线程安全吗?
  • 随笔之 ClickHouse 列式分析数据库安装注意事项及基准测试
  • clickhouse 中文数据的正则匹配
  • 【盘古100Pro+开发板实验例程】FPGA学习 | 3X3图像矩阵生成 | 图像实验指导手册
  • Exporters | 安装mysqld_exporter
  • SpringCloud相关知识
  • 晨控CK-GW08S与汇川AC系列PLC配置Ethernet/IP通讯连接手册
  • DevOps平台大比拼:Gitee、Jenkins与CircleCI如何选型?
  • 乐思 AI 智能识别平台(基于 YOLO,.NET+Vue3 开发)开源指南
  • 【秋招笔试】2025.08.03-拼多多笔试真题-第二题
  • 自然语言理解领域算法模型演进图谱
  • 2025最新、UI媲美豆包、DeepSeek等AI大厂的AIGC系统 - IMYAI源码部署教程
  • 多级表头的导出
  • 人大金仓数据库常见问题(持续更新)
  • SJW-app-1