【精选】设计模式——工厂设计模式

工厂设计模式是一种创建型设计模式,其主要目的是通过将对象的创建过程封装在一个工厂类中来实现对象的创建。这样可以降低客户端与具体产品类之间的耦合度,也便于代码的扩展和维护。
在这里插入图片描述
在这里插入图片描述

工厂设计模式:

以下是Java中两个常见的工厂设计模式示例:
在这里插入图片描述

1. 简单工厂模式

在这里插入图片描述

简单工厂模式又称静态工厂模式,通过一个工厂类统一创建各种不同类型的产品对象。下面以创建不同形状的图形为例。

// 定义图形接口
interface Shape {void draw();
}// 实现具体图形类
class Circle implements Shape {@Overridepublic void draw() {System.out.println("Drawing a circle.");}
}class Rectangle implements Shape {@Overridepublic void draw() {System.out.println("Drawing a rectangle.");}
}class Triangle implements Shape {@Overridepublic void draw() {System.out.println("Drawing a triangle.");}
}// 简单工厂类
class ShapeFactory {// 根据传入参数创建对应的图形对象public static Shape createShape(String shapeType) {if (shapeType.equalsIgnoreCase("circle")) {return new Circle();} else if (shapeType.equalsIgnoreCase("rectangle")) {return new Rectangle();} else if (shapeType.equalsIgnoreCase("triangle")) {return new Triangle();}return null;}
}// 使用示例
public class SimpleFactoryExample {public static void main(String[] args) {Shape circle = ShapeFactory.createShape("circle");circle.draw(); // 输出:Drawing a circle.Shape rectangle = ShapeFactory.createShape("rectangle");rectangle.draw(); // 输出:Drawing a rectangle.Shape triangle = ShapeFactory.createShape("triangle");triangle.draw(); // 输出:Drawing a triangle.}
}

2. 工厂方法模式

工厂方法模式定义了一个创建对象的接口,但具体由子类决定实例化哪个类。下面以创建不同类型的日志记录器为例。

// 定义日志记录器接口
interface Logger {void log(String message);
}// 实现具体日志记录器类
class FileLogger implements Logger {@Overridepublic void log(String message) {System.out.println("Writing log to file: " + message);}
}class ConsoleLogger implements Logger {@Overridepublic void log(String message) {System.out.println("Writing log to console: " + message);}
}// 抽象工厂类
abstract class LoggerFactory {// 创建日志记录器对象public abstract Logger createLogger();
}// 具体工厂类,用于创建文件日志记录器
class FileLoggerFactory extends LoggerFactory {@Overridepublic Logger createLogger() {return new FileLogger();}
}// 具体工厂类,用于创建控制台日志记录器
class ConsoleLoggerFactory extends LoggerFactory {@Overridepublic Logger createLogger() {return new ConsoleLogger();}
}// 使用示例
public class FactoryMethodExample {public static void main(String[] args) {LoggerFactory fileLoggerFactory = new FileLoggerFactory();Logger fileLogger = fileLoggerFactory.createLogger();fileLogger.log("Error occurred."); // 输出:Writing log to file: Error occurred.LoggerFactory consoleLoggerFactory = new ConsoleLoggerFactory();Logger consoleLogger = consoleLoggerFactory.createLogger();consoleLogger.log("Warning."); // 输出:Writing log to console: Warning.}
}

好的,下面继续介绍另外两个常见的工厂设计模式示例:

3. 抽象工厂模式

抽象工厂模式提供了一个创建一系列相关或者相互依赖对象的接口,而无需指定它们具体的类。下面以创建不同操作系统的界面组件为例。

// 定义操作系统界面组件接口
interface Button {void render();
}interface TextField {void render();
}// 实现Windows操作系统界面组件
class WindowsButton implements Button {@Overridepublic void render() {System.out.println("Rendering a Windows button.");}
}class WindowsTextField implements TextField {@Overridepublic void render() {System.out.println("Rendering a Windows text field.");}
}// 实现Mac操作系统界面组件
class MacButton implements Button {@Overridepublic void render() {System.out.println("Rendering a Mac button.");}
}class MacTextField implements TextField {@Overridepublic void render() {System.out.println("Rendering a Mac text field.");}
}// 抽象工厂接口
interface GUIFactory {Button createButton();TextField createTextField();
}// 具体工厂类,用于创建Windows风格的界面组件
class WindowsGUIFactory implements GUIFactory {@Overridepublic Button createButton() {return new WindowsButton();}@Overridepublic TextField createTextField() {return new WindowsTextField();}
}// 具体工厂类,用于创建Mac风格的界面组件
class MacGUIFactory implements GUIFactory {@Overridepublic Button createButton() {return new MacButton();}@Overridepublic TextField createTextField() {return new MacTextField();}
}// 使用示例
public class AbstractFactoryExample {public static void main(String[] args) {// 创建Windows风格的界面组件GUIFactory windowsFactory = new WindowsGUIFactory();Button windowsButton = windowsFactory.createButton();windowsButton.render(); // 输出:Rendering a Windows button.TextField windowsTextField = windowsFactory.createTextField();windowsTextField.render(); // 输出:Rendering a Windows text field.// 创建Mac风格的界面组件GUIFactory macFactory = new MacGUIFactory();Button macButton = macFactory.createButton();macButton.render(); // 输出:Rendering a Mac button.TextField macTextField = macFactory.createTextField();macTextField.render(); // 输出:Rendering a Mac text field.}
}

抽象工厂模式可以创建一系列相关的产品对象,例如上述示例中的不同操作系统的界面组件。使用此模式可以确保所创建的产品对象是相互配套的。

4. 单例工厂模式

单例工厂模式通过工厂类控制只创建一个对象实例,供客户端使用。下面以创建数据库连接对象为例。

// 数据库连接类
class DBConnection {private static DBConnection instance;// 私有构造函数,防止通过new关键字创建实例private DBConnection() {}public static synchronized DBConnection getInstance() {if (instance == null) {instance = new DBConnection();}return instance;}public void connect() {System.out.println("Connecting to the database...");}
}// 使用示例
public class SingletonFactoryExample {public static void main(String[] args) {DBConnection connection1 = DBConnection.getInstance();connection1.connect(); // 输出:Connecting to the database...DBConnection connection2 = DBConnection.getInstance();connection2.connect(); // 输出:Connecting to the database...System.out.println(connection1 == connection2); // 输出:true,表示只创建了一个实例}
}

单例工厂模式确保在整个应用程序中只有一个实例被创建和共享,避免了多次创建相同对象的开销,并且能够提供全局访问点以便于其他对象使用。

工厂设计模式具有以下优点:

  1. 解耦客户端和具体产品类:工厂类负责对象的创建,客户端只需要通过工厂类获取所需的对象,无需直接与具体产品类交互,从而降低了客户端与具体产品类之间的耦合度。
  2. 代码的扩展性和维护性好:当需要增加新的产品时,只需添加相应的产品类和对应的工厂方法即可,不需要修改已有的代码,符合开闭原则(对扩展开放,对修改关闭)。
  3. 更好地封装和隐藏了对象的创建过程:客户端无需关心对象的创建细节,只需调用工厂类的方法即可得到所需的对象。
  4. 提高了程序的可扩展性:通过工厂类统一创建对象,可以方便地切换产品系列或者替换具体的工厂类,符合依赖倒置原则。

然而,工厂设计模式也存在一些缺点:

  1. 增加了系统的复杂度:引入工厂类会增加系统的类和对象数量,增加了代码量和理解难度。
  2. 不够灵活:由于工厂类负责对象的创建,如果需要创建具有不同特性的对象,可能需要修改工厂类的代码,违反了开闭原则。
  3. 难以扩展新的产品族:当需要扩展一个新的产品族时,需要修改工厂类的代码,违反了开闭原则。

因此,在使用工厂设计模式时需要根据实际情况权衡其优缺点,并选择最适合的设计方案。

除了上述列举的几种工厂设计模式,还有一些其他的变体和衍生形式:

  1. 多个工厂方法:某些情况下,可以在抽象工厂类中定义多个工厂方法,每个工厂方法分别用于创建不同类型的产品对象。这样可以更加灵活地处理不同类型的产品。
  2. 延迟初始化工厂:在工厂类中使用延迟初始化技术,只有在需要时才创建具体产品对象。这样可以节省系统资源,提高性能。
  3. 反射工厂:通过Java反射机制,根据传入的类名动态创建对象。这种方式可以在运行时动态地创建对象,灵活性更高。
  4. 简单工厂与抽象工厂结合:有时候可以将简单工厂和抽象工厂结合使用,以实现更复杂的对象创建过程。例如,在抽象工厂中定义一个工厂方法来创建简单工厂,然后再由简单工厂负责创建具体产品对象。

无论是哪种工厂设计模式,都要根据实际需求选择合适的方案。工厂设计模式在许多软件系统中都得到了广泛应用,它们能够提供良好的代码结构、可扩展性和灵活性,使得系统更易于维护和拓展。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/208960.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ 关于结构体struct的一些总结

文章目录 一、 结构体(struct)是什么?(1)概念(2)struct 与 calss 的区别 二、定义、声明与初始化(1)三种定义结构体的方法:(2)结构体变量初始化 三、结构体嵌…

C++实现进程端口网络数据接收系统设计示例程序

一、问题描述 最近做了一道简单的系统设计题&#xff0c;大概描述如下&#xff1a; 1.一个进程可以绑定多个端口&#xff0c;用于监听接收网络中的数据&#xff0c;但是一个端口只能被一个进程占用 2.1 < pid < 65535, 1 < port < 100000, 1 < topNum < 5, …

C++:vector增删查改模拟实现

C:vector增删查改模拟实现 前言一、迭代器1.1 非const迭代器&#xff1a;begin()、end()1.2 const迭代器&#xff1a;begin()、end() 二、构造函数、拷贝构造函数、赋值重载、析构函数模拟实现2.1 构造函数2.1.1 无参构造2.1.2 迭代器区间构造2.1.3 n个值构造 2.2 拷贝构造2.3 …

vue路由导航守卫(全局守卫、路由独享守卫、组件内守卫)

目录 一、什么是Vue路由导航守卫&#xff1f; 二、全局守卫 1、beforeEach 下面是一个beforeEach的示例代码&#xff1a; 2、beforeResolve 下面是一个beforeResolve的示例代码&#xff1a; 3、afterEach 下面是一个afterEach的示例代码&#xff1a; 三、路由独享守卫…

044:vue中引用json数据的方法

第044个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 &#xff08;1&#xff09;提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使…

多相Buck的工作原理

什么是多相Buck电源&#xff1f; 多相电源控制器是一种通过同时控制多个电源相位的设备&#xff0c;以提供稳定的电力供应。相位是指电源中的电流和电压波形。多相控制器的设计旨在最大程度地减小电力转换系统的纹波&#xff0c;并提高整体能效。它通常包含一系列的功率级联&a…

结构化布线系统

满足下列需求&#xff1a; 1.标准化&#xff1a;国际、国家标准。 2.实用性&#xff1a;针对实际应用的需要和特点来建设系统。 3.先进性&#xff1a;采用国际最新技术。5-10年内技术不落后。 4.开放性&#xff1a;整个系统的开放性。 5.结构化、层次化&#xff1a;易于管理和维…

Matplotlib数据可视化

绘图基础语法 &#xff11; 创建画布并且创建子图 首先创建一个空白的画布&#xff0c;并且可以将画布分为几个部分&#xff0c;这样就可以在同一附图上绘制多个图像。 plt.figure 创建一个空白画布&#xff0c;可以指定画布大小、像素 figure.add_subplot 创建并且选中子…

【web安全】文件读取与下载漏洞

前言 菜某整理仅供学习&#xff0c;有误请赐教。 概念 个人理解&#xff1a;就是我们下载一个文件会传入一个参数&#xff0c;但是我们可以修改参数&#xff0c;让他下载其他的文件。因为是下载文件&#xff0c;所以我们可以看到文件里面的源码&#xff0c;内容。 文件读取…

swiftUi——颜色

在SwiftUI中&#xff0c;您可以使用Color结构来表示颜色。Color可以直接使用预定义的颜色&#xff0c;例如.red、.blue、.green等&#xff0c;也可以使用自定义的RGB值、十六进制颜色代码或者系统提供的颜色。 1. 预定义颜色 Text("预定义颜色").foregroundColor(.…

Swing程序设计(9)复选框,下拉框

文章目录 前言一、复选框二、下拉框总结 前言 该篇文章简单介绍了Java中Swing组件里的复选框组件、列表框组件、下拉框组件&#xff0c;这些在系统中都是常用的组件。 一、复选框 复选框&#xff08;JCheckBox&#xff09;在Swing组件中的使用也非常广泛&#xff0c;一个方形方…

hadoop安装与配置-shell脚本一键安装配置(集群版)

文章目录 前言一、安装准备1. 搭建集群 二、使用shell脚本一键安装1. 复制脚本2. 增加执行权限3. 分发脚本4. 执行脚本5. 加载用户环境变量 三、启动与停止1. 启动/停止hadoop集群(1) 复制hadoop集群启动脚本(2) 增加执行权限(3) 启动hadoop集群(4) 停止hadoop集群(5) 重启hado…

智慧社区前景无限,科技引领未来发展

社区是城镇化发展的标志&#xff0c;作为人类现代社会的生活的基本圈子&#xff0c;是人类生活离不开的地方&#xff0c;社区人口密度大、车辆多&#xff0c;管理无序&#xff0c;社区的膨胀式发展多多少少带来一定的管理上的缺失。社区作为智慧城市建设的重要一环&#xff0c;…

编译基于LIO-SAM的liorf“Large velocity, reset IMU-preintegration!“

使用LIO-SAM修改的代码liorf&#xff08;因自己使用的IMU传感器是 6-axis ouster&#xff09;&#xff1a; LIO-SAM代码连接&#xff1a; https://github.com/TixiaoShan/LIO-SAM liorf代码连接&#xff1a; https://github.com/YJZLuckyBoy/liorf 编译运行出现错误&#…

eve-ng山石网科HillStone镜像部署

HillStone 部署 author&#xff1a;leadlife data&#xff1a;2023/12/4 mains&#xff1a;EVE-ng HillStone 镜像部署 - use hillstone-sg6000 default&#xff1a;hillstone/hillstone 传输 scp hillstone-sg6000.zip root192.168.3.130:/opt/unetlab/addons/qemu/部署 cd …

echarts绘制一个环形图

其他echarts&#xff1a; echarts绘制一个柱状图&#xff0c;柱状折线图 echarts绘制一个饼图 echarts绘制一个环形图2 效果图&#xff1a; 代码&#xff1a; <template><div class"wrapper"><!-- 环形图 --><div ref"doughnutChart…

C++STL的string(超详解)

文章目录 前言C语言的字符串 stringstring类的常用接口string类的常见构造string (const string& str);string (const string& str, size_t pos, size_t len npos); capacitysize和lengthreserveresizeresize可以删除数据 modify尾插插入字符插入字符串 inserterasere…

如何将腾讯混元大模型AI接入自己的项目里(中国版本ChatGPT)

如何将腾讯混元大模型AI接入自己的项目里 一、腾讯混元大模型API二、使用步骤1、接口2、请求参数3、请求参数示例4、接口 返回示例 三、 如何获取appKey和uid1、申请appKey:2、获取appKey和uid 四、重要说明 一、腾讯混元大模型API 基于腾讯混元大模型AI的智能文本对话AI机器人…

TypeScript 的修饰符(modifier)和装饰器(decorator)

装饰器是一种特殊类型的声明&#xff0c;它能够被附加到类声明....上。 装饰器使用 expression这种形式

使用消息队列遇到的问题—kafka

目录 1 分区2 消费者3 Kafka 如何保证消息的消费顺序&#xff1f;3.1 方案一3.2 方案二 4 消息积压 在项目中使用kafka作为消息队列&#xff0c;核心工作是创建生产者—包装数据&#xff1b;创建消费者----包装数据。 欠缺一些思考&#xff0c;特此梳理项目中使用kafka遇到的一…