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

小谈设计模式(9)—工厂方法模式

小谈设计模式(9)—工厂方法模式

  • 专栏介绍
    • 专栏地址
    • 专栏介绍
  • 工厂方法模式
    • 角色分类
      • 抽象产品(Abstract Product)
      • 具体产品(Concrete Product)
      • 抽象工厂(Abstract Factory)
      • 具体工厂(Concrete Factory)
    • 核心思想
    • Java代码实现:
      • 假设有一个汽车工厂,可以生产不同类型的汽车,包括小轿车和SUV。首先定义一个抽象汽车类(AbstractProduct):
      • 然后定义具体的小轿车类(ConcreteProduct1)和SUV类(ConcreteProduct2),它们都继承自抽象汽车类:
      • 接下来定义抽象汽车工厂类(AbstractFactory),其中包含一个创建汽车的抽象方法:
      • 然后定义具体的小轿车工厂类(ConcreteFactory1)和SUV工厂类(ConcreteFactory2),它们都继承自抽象汽车工厂类:
      • 最后,在客户端代码中使用工厂方法来创建汽车对象:
      • 输出结果为
      • 分析
    • 优缺点分析
      • 优点
        • 符合开闭原则
        • 封装了对象的创建过程
        • 降低了客户端和具体产品的耦合
        • 可以通过配置文件等方式动态指定具体工厂类
      • 缺点
        • 增加了系统的复杂度
        • 增加了代码的数量
        • 客户端需要知道具体工厂类

专栏介绍

专栏地址

link

专栏介绍

主要对目前市面上常见的23种设计模式进行逐一分析和总结,希望有兴趣的小伙伴们可以看一下,会持续更新的。希望各位可以监督我,我们一起学习进步,加油,各位。
在这里插入图片描述

工厂方法模式

工厂方法模式是一种创建型设计模式,它定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法模式将对象的实例化推迟到子类中进行。

角色分类

抽象产品(Abstract Product)

定义了产品的接口,是具体产品类的共同父类或接口。

具体产品(Concrete Product)

实现了抽象产品接口的具体类。

抽象工厂(Abstract Factory)

定义了创建产品的接口,包含一个或多个创建产品的抽象方法。

具体工厂(Concrete Factory)

实现了抽象工厂接口,负责实例化具体产品。
在这里插入图片描述

核心思想

将对象的创建与使用分离,客户端通过调用工厂方法来创建对象,而不是直接实例化具体产品。这样做的好处是,客户端只需要知道抽象产品和抽象工厂的存在,而无需关心具体产品的细节。当需要创建不同类型的产品时,只需要实现对应的具体产品和具体工厂即可,而不需要修改客户端的代码。

在这里插入图片描述

Java代码实现:

假设有一个汽车工厂,可以生产不同类型的汽车,包括小轿车和SUV。首先定义一个抽象汽车类(AbstractProduct):

public abstract class Car {public abstract void drive();
}

然后定义具体的小轿车类(ConcreteProduct1)和SUV类(ConcreteProduct2),它们都继承自抽象汽车类:

public class SedanCar extends Car {@Overridepublic void drive() {System.out.println("Driving sedan car...");}
}public class SUV extends Car {@Overridepublic void drive() {System.out.println("Driving SUV...");}
}

接下来定义抽象汽车工厂类(AbstractFactory),其中包含一个创建汽车的抽象方法:

public abstract class CarFactory {public abstract Car createCar();
}

然后定义具体的小轿车工厂类(ConcreteFactory1)和SUV工厂类(ConcreteFactory2),它们都继承自抽象汽车工厂类:

public class SedanCarFactory extends CarFactory {@Overridepublic Car createCar() {return new SedanCar();}
}public class SUVFactory extends CarFactory {@Overridepublic Car createCar() {return new SUV();}
}

最后,在客户端代码中使用工厂方法来创建汽车对象:

public class Client {public static void main(String[] args) {CarFactory factory1 = new SedanCarFactory();Car sedanCar = factory1.createCar();sedanCar.drive();CarFactory factory2 = new SUVFactory();Car suv = factory2.createCar();suv.drive();}
}

输出结果为

Driving sedan car...
Driving SUV...

分析

通过工厂方法模式,客户端代码只需要与抽象产品和抽象工厂进行交互,而无需关心具体产品的创建过程。当需要新增其他类型的汽车时,只需要实现对应的具体产品和具体工厂即可,而不需要修改客户端的代码,实现了代码的可扩展性和可维护性。
在这里插入图片描述

优缺点分析

优点

符合开闭原则

工厂方法模式通过引入抽象工厂和具体工厂的概念,使得系统的扩展性更好。当需要新增一种产品时,只需要新增对应的具体产品和具体工厂,而不需要修改已有的代码,符合开闭原则。

封装了对象的创建过程

客户端只需要关心抽象产品和抽象工厂,而无需关心具体产品的创建过程。具体产品的创建过程被封装在具体工厂中,使得客户端代码更加简洁、可读性更高。

降低了客户端和具体产品的耦合

客户端只依赖于抽象产品和抽象工厂,而不依赖于具体产品。这样可以使客户端代码与具体产品解耦,提高代码的灵活性和可维护性。

可以通过配置文件等方式动态指定具体工厂类

工厂方法模式可以通过配置文件、反射等方式动态指定具体工厂类,从而实现更加灵活的对象创建方式。
在这里插入图片描述

缺点

增加了系统的复杂度

引入抽象工厂和具体工厂的概念,使得系统的结构变得更加复杂。如果系统中只有少量的产品,使用工厂方法模式可能会显得过于复杂,不利于维护和理解。

增加了代码的数量

工厂方法模式需要定义抽象产品、具体产品、抽象工厂、具体工厂等多个类,这增加了代码的数量。对于简单的项目,使用工厂方法模式可能会显得冗余。

客户端需要知道具体工厂类

客户端需要知道具体工厂类的存在,这增加了客户端的依赖。如果具体工厂类的创建逻辑发生变化,客户端代码也需要相应的修改。

在这里插入图片描述

相关文章:

小谈设计模式(9)—工厂方法模式

小谈设计模式(9)—工厂方法模式 专栏介绍专栏地址专栏介绍 工厂方法模式角色分类抽象产品(Abstract Product)具体产品(Concrete Product)抽象工厂(Abstract Factory)具体工厂&#x…...

Android etc1tool之png图片转换pkm 和 zipalign简介

关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、商业变现、人工智能等,希望大家多多支持。 目录 一、导读二、etc1tool2.1、用法 三、zipalign3.1 使用 四…...

Spring Boot快速入门:构建简单的Web应用

SpringBoot Spring Boot是一个用于简化Spring应用程序开发的框架,它通过提供开箱即用的配置和一组常用的功能,使得构建高效、可维护的应用变得非常容易。在本篇博客中,我们将一步步地介绍如何快速入门Spring Boot,并构建一个简单的…...

JAVA 泛型、序列化和复制

泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。比如我们要写一个排序方法,能够对整型数组、字符串数组甚至其他任何类型的数组进行排序&a…...

以太网基础学习(二)——ARP协议

一、什么是MAC地址 MAC地址(英语:Media Access Control Address),直译为媒体访问控制位址,也称为局域网地址(LAN Address),MAC位址,以太网地址(Ethernet Addr…...

【Java-LangChain:使用 ChatGPT API 搭建系统-4】评估输入-分类

第三章,评估输入-分类 如果您正在构建一个允许用户输入信息的系统,首先要确保人们在负责任地使用系统,以及他们没有试图以某种方式滥用系统,这是非常重要的。 在本章中,我们将介绍几种策略来实现这一目标。 我们将学习…...

嵌入式Linux应用开发-驱动大全-第一章同步与互斥③

嵌入式Linux应用开发-驱动大全-第一章同步与互斥③ 第一章 同步与互斥③1.4 Linux锁的介绍与使用1.4.1 锁的类型1.4.1.1 自旋锁1.4.1.2 睡眠锁 1.4.2 锁的内核函数1.4.2.1 自旋锁1.4.2.2 信号量1.4.2.3 互斥量1.4.2.4 semaphore和 mutex的区别 1.4.3 何时用何种锁1.4.4 内核抢占…...

树的存储结构以及树,二叉树,森林之间的转换

目录 1.双亲表示法 2.孩子链表 3.孩子兄弟表示法 4.树与二叉树的转换 (1)树转换为二叉树 (2)二叉树转换成树 5.二叉树与森林的转化 (1)森林转换为二叉树 以下树为例 1.双亲表示法 双亲表示法定义了…...

【AI视野·今日NLP 自然语言处理论文速览 第四十二期】Wed, 27 Sep 2023

AI视野今日CS.NLP 自然语言处理论文速览 Wed, 27 Sep 2023 Totally 50 papers 👉上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Attention Satisfies: A Constraint-Satisfaction Lens on Factual Errors of Language Models Authors Mert …...

华为云云耀云服务器L实例评测|部署个人在线电子书库 calibre

华为云云耀云服务器L实例评测|部署个人在线电子书库 calibre 一、云耀云服务器L实例介绍1.1 云服务器介绍1.2 应用场景1.3 支持镜像 二、云耀云服务器L实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置 三、部署 calibre3.1 calibre 介绍3.2 Docker 环境搭建3.3 c…...

代码随想录刷题 Day28

216.组合总和III 和前一个题一样,照着自己就能写出来,就多了一个判断结果是不是等于n的逻辑。有两个地方可以剪纸,一个是当和已经大于要找的时候直接返回,另一个是当剩余元素少于三个的时候直接返回(第一层递归是少于…...

【生命周期】

生命周期 1 引出生命周期2 分析生命周期3 总结生命周期 1 引出生命周期 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta …...

【C语言 模拟实现memcpy函数、memcpy函数】

C语言程序设计笔记---027 C语言之模拟实现memcpy函数、memcpy函数1、介绍memcpy函数1.1、模拟实现memcpy函数 2、介绍memmove函数2.1、模拟实现memmove函数 3、结语 C语言之模拟实现memcpy函数、memcpy函数 前言&#xff1a; 通过C语言内存函数的知识&#xff0c;这篇将对memc…...

opencv视频文件的读取,处理与保存

文章目录 opencv视频文件的读取&#xff0c;处理与保存一、视频文件的读取&#xff1a;1、cv::VideoCapture是OpenCV库中用于处理视频输入的类&#xff0c;它提供了一种简单的方法来从摄像头&#xff0c;视频文件、或图像序列中读取帧&#xff1b;&#xff08;1&#xff09;打开…...

java - 七大比较排序 - 详解

前言 本篇介绍了七大比较排序&#xff0c;直接插入排序&#xff0c;希尔排序&#xff0c;冒泡排序&#xff0c;堆排序&#xff0c;选择排序&#xff0c;快速排序&#xff0c;归并排序&#xff0c;一些简单思想代码实现&#xff0c;如有错误&#xff0c;请在评论区指正&#xf…...

项目集成七牛云存储sdk

以PHP为例 第一步&#xff1a;下载sdk PHP SDK_SDK 下载_对象存储 - 七牛开发者中心 sdk下载成功之后&#xff0c;将sdk放入项目中&#xff0c;目录选择以自己项目实际情况而定。 注意&#xff1a;在examples目录中有各种上传文件的参考示例&#xff0c;这里我们主要参考的是…...

docker-compose一键启动neo4j

下载镜像 docker pull neo4j:3.5.22-community 编写配置文件 参考文档 编写docker-compose.yml文件 version: "3"services:neo4j:image: neo4j:3.5.22-communitycontainer_name: neo4j restart: alwaysports:- 7474:7474- 7687:7687environment:- NEO4J_AUTH:ne…...

深入剖析@ConfigurationProperties注解

当我们构建Spring Boot应用程序时&#xff0c;配置属性通常是不可或缺的一部分。Spring Boot提供了多种方式来管理这些属性&#xff0c;其中之一是使用ConfigurationProperties注解。这篇博客将详细解释ConfigurationProperties注解以及如何使用它来管理和映射配置属性。 什么…...

北京开发APP需要多少钱

北京开发一个移动应用&#xff08;APP&#xff09;的费用因多种因素而异&#xff0c;包括项目的规模、复杂性、所需功能、设计要求、技术选择、开发团队的经验和地理位置等。一般来说&#xff0c;北京的APP开发费用通常较高&#xff0c;因为这是中国的主要技术和创新中心之一&a…...

self-attention、transformer、bert理解

参考李宏毅老师的视频 https://www.bilibili.com/video/BV1LP411b7zS?p2&spm_id_frompageDriver&vd_sourcec67a2725ac3ca01c38eb3916d221e708 一个输入&#xff0c;一个输出&#xff0c;未考虑输入之间的关系&#xff01;&#xff01;&#xff01; self-attention…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...