当前位置: 首页 > 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.xdnf.cn/news/1240111.html

相关文章:

  • 134页PPT华为项目管理之道PPT
  • 期权投资盈利之道书籍推荐
  • Scrapy爬虫集成MongoDB存储
  • 13.Home-面板组件封装
  • 区块链 和 一致性哈希的结合
  • 基于高斯光束干涉的微球体相位成像系统设计与实现
  • JVM学习日记(十六)Day16——性能监控与调优(三)
  • Python实现Word转PDF全攻略:从入门到实战
  • Linux U盘识别问题排查指南
  • Spring Boot + ShardingSphere 分库分表实战
  • 机器学习——决策树(DecisionTree)+ 过采样 + 交叉验证 案例:电信客户流失数据
  • 飞算科技:用自主创新技术,为行业数字化转型按下 “加速键”
  • ICCV2025 Tracking相关paper汇总和解读(19篇)
  • 13015计算机系统原理-速记宝典
  • Web 开发 12
  • 移动前后端全栈项目
  • 小迪安全v2023学习笔记(五十一讲)—— 持续更新中
  • Nexus配置npm私有仓库
  • Java项目:基于SSM框架实现的商铺租赁管理系统【ssm+B/S架构+源码+数据库+毕业论文+开题报告+任务书+远程部署】
  • LLM大模型开发-SpringAI:ChatClient、Ollama、Advisor
  • io_destroy系统调用及示例
  • 基于 LangChain + 通义千问 + bge-large 中文 Embedding 搭建一个RAG问答示例
  • FastAPI入门:安全性
  • 第12届蓝桥杯Scratch图形化【省赛】初级组 2021年4月24日
  • MySQL学习之MVCC多版本并发控制
  • python常用数据类型
  • 13.Redis 的级联复制
  • 03.一键编译安装Redis脚本
  • sqli-labs:Less-23关卡详细解析
  • 【运维基础】Linux 硬盘分区管理