设计模式使用场景实现示例及优缺点(创建型模式——工厂方法模式、抽象工厂模式)

创建型模式

工厂方法模式 (Factory Method Pattern)

工厂方法模式(Factory Method Pattern)是一种创建型设计模式,提供了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法模式让类的实例化推迟到子类。这样,客户端代码将依赖于具体子类的实现,而不是直接依赖于具体的对象。

适用场景

  1. 代码需要处理不同类型的对象,但不希望将对象的创建逻辑耦合到代码中

    • 比如,在处理不同数据库类型(如 MySQL、PostgreSQL)时,可以使用工厂方法模式来创建数据库连接对象,而不需要在客户端代码中直接引用具体的数据库类。
  2. 代码中涉及复杂的对象创建过程

    • 如果对象的创建过程很复杂,包括许多步骤和配置,工厂方法模式可以将创建逻辑集中在一个地方,简化客户端代码。
  3. 客户端代码不应依赖于具体类来创建对象

    • 工厂方法模式使客户端代码依赖于抽象类或接口,从而提高代码的灵活性和可扩展性。

实现示例(Java)

下面是一个使用工厂方法模式的示例,展示如何创建不同类型的日志记录器(如文件日志记录器和数据库日志记录器):

1. 定义产品接口或抽象类
public interface Logger {void log(String message);
}
2. 具体产品类实现接口或继承抽象类
public class FileLogger implements Logger {@Overridepublic void log(String message) {System.out.println("File logger: " + message);}
}public class DatabaseLogger implements Logger {@Overridepublic void log(String message) {System.out.println("Database logger: " + message);}
}
3. 定义工厂方法的抽象类
public abstract class LoggerFactory {public abstract Logger createLogger();public void log(String message) {Logger logger = createLogger();logger.log(message);}
}
4. 具体工厂类实现工厂方法
public class FileLoggerFactory extends LoggerFactory {@Overridepublic Logger createLogger() {return new FileLogger();}
}public class DatabaseLoggerFactory extends LoggerFactory {@Overridepublic Logger createLogger() {return new DatabaseLogger();}
}
5. 客户端代码
public class Main {public static void main(String[] args) {LoggerFactory factory;Logger logger;// 使用文件日志记录器factory = new FileLoggerFactory();factory.log("This is a file log message.");// 使用数据库日志记录器factory = new DatabaseLoggerFactory();factory.log("This is a database log message.");}
}

工厂方法模式的优点

  1. 代码解耦

    • 客户端代码依赖于抽象产品接口或抽象工厂,而不是具体的产品类,从而实现了代码的解耦。
  2. 提高灵活性

    • 新的具体产品可以通过实现产品接口并创建相应的具体工厂类来添加,而无需修改现有代码。
  3. 单一职责原则

    • 将对象创建的责任委派给具体工厂类,符合单一职责原则。

工厂方法模式的缺点

  1. 类的数量增加

    • 每添加一种新的产品类型,都需要创建一个具体产品类和相应的具体工厂类,可能会导致类的数量增加。
  2. 实现复杂

    • 工厂方法模式可能会使代码结构变得复杂,特别是在存在多个产品层次结构时。

总结

工厂方法模式通过将对象的创建过程封装在工厂方法中,实现了客户端代码与具体产品类的解耦。它适用于对象创建过程复杂、多种类型的对象创建等场景,有助于提高代码的灵活性和可维护性。

抽象工厂模式

抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。抽象工厂模式通过对产品类的工厂进行抽象,使得一个工厂可以生产多种类型的产品。

适用场景

  1. 系统需要独立于产品创建的方式时

    • 客户端代码不需要知道具体产品的创建过程,只需要知道如何使用抽象接口。
  2. 系统有多个产品系列,每个系列有多种类型的产品时

    • 例如,GUI库可能提供不同风格的窗口和按钮(如Windows风格和Mac风格),抽象工厂可以提供一个接口来创建不同风格的组件。
  3. 需要保证产品系列的一致性时

    • 抽象工厂模式确保同一个工厂创建的产品系列是兼容的。

实现示例(Java)

以下是一个简单的抽象工厂模式的实现示例,展示如何创建不同风格的GUI组件(如按钮和复选框)。

1. 定义抽象产品接口
// 抽象产品A
public interface Button {void paint();
}// 抽象产品B
public interface Checkbox {void paint();
}
2. 具体产品类实现抽象产品接口
// 具体产品A1
public class WindowsButton implements Button {@Overridepublic void paint() {System.out.println("Windows Button");}
}// 具体产品A2
public class MacButton implements Button {@Overridepublic void paint() {System.out.println("Mac Button");}
}// 具体产品B1
public class WindowsCheckbox implements Checkbox {@Overridepublic void paint() {System.out.println("Windows Checkbox");}
}// 具体产品B2
public class MacCheckbox implements Checkbox {@Overridepublic void paint() {System.out.println("Mac Checkbox");}
}
3. 定义抽象工厂接口
public interface GUIFactory {Button createButton();Checkbox createCheckbox();
}
4. 具体工厂类实现抽象工厂接口
// 具体工厂1
public class WindowsFactory implements GUIFactory {@Overridepublic Button createButton() {return new WindowsButton();}@Overridepublic Checkbox createCheckbox() {return new WindowsCheckbox();}
}// 具体工厂2
public class MacFactory implements GUIFactory {@Overridepublic Button createButton() {return new MacButton();}@Overridepublic Checkbox createCheckbox() {return new MacCheckbox();}
}
5. 客户端代码
public class Application {private Button button;private Checkbox checkbox;// 构造函数接收抽象工厂类型public Application(GUIFactory factory) {button = factory.createButton();checkbox = factory.createCheckbox();}// 模拟绘制方法public void paint() {button.paint();checkbox.paint();}public static void main(String[] args) {// 可根据需求选择具体工厂GUIFactory factory = new WindowsFactory();Application app = new Application(factory);app.paint();factory = new MacFactory();app = new Application(factory);app.paint();}
}

注释说明

  1. 抽象产品接口

    • ButtonCheckbox 是两个抽象产品接口,定义了产品的通用行为(如 paint 方法)。
  2. 具体产品类

    • WindowsButtonMacButtonWindowsCheckboxMacCheckbox 是具体产品类,它们实现了抽象产品接口,提供具体的产品行为。
  3. 抽象工厂接口

    • GUIFactory 是抽象工厂接口,定义了创建一系列相关产品的方法(如 createButtoncreateCheckbox)。
  4. 具体工厂类

    • WindowsFactoryMacFactory 是具体工厂类,它们实现了抽象工厂接口,提供了具体的产品创建方法。
  5. 客户端代码

    • Application 类通过依赖抽象工厂接口来创建产品。这样,客户端代码与具体产品类解耦,便于扩展和维护。

总结

抽象工厂模式通过对产品类和工厂类的抽象,使得客户端代码可以独立于具体产品类和工厂类进行工作。它适用于需要创建一系列相关或相互依赖对象的系统,有助于提高代码的灵活性和一致性。

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

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

相关文章

关于MySQL mvcc

innodb mvcc mvcc 多版本并发控制 在RR isolution 情况下 trx在启动的时候就拍了个快照。这个快照是基于整个数据库的。 其实这个快照并不是说拷贝整个数据库。并不是说要拷贝出这100个G的数据。 innodb里面每个trx有一个唯一的trxID 叫做trx id .在trx 开始的时候向innodb系…

嵌入式音频处理技术的现在发展及未来的方向

嵌入式音频处理技术:从音频流媒体到声音识别 嵌入式音频处理技术的迅猛发展正在改变我们的生活方式,从音频流媒体到声音识别,这个领域为人们的生活和工作带来了巨大的影响。本文将探讨嵌入式音频处理技术的最新趋势和应用,以及提…

逻辑回归模型(非回归问题,而是解决二分类问题)

目录: 一、Sigmoid激活函数:二、逻辑回归介绍:三、决策边界四、逻辑回归模型训练过程:1.训练目标:2.梯度下降调整参数: 一、Sigmoid激活函数: Sigmoid函数是构建逻辑回归模型的重要激活函数&am…

openlayers更改点坐标

我现在的需求是无人机点位根据ws传输的经纬度改变位置,在网上查了很多资料,终于是做出来了,如果有问题请指出。 效果图,无人机可以来回移动 这里是核心代码 // 添加飞机点位图层let vectorLayerpointfunction DronepointLayer()…

Mercer 条件的基本概念及证明

Mercer 条件 是核函数理论中的一个重要概念,它确保了一个给定的对称函数可以表示为某个高维特征空间中的内积。这个条件在支持向量机(SVM)和其他基于核方法的机器学习算法中非常重要。 文章目录 基本介绍Mercer 条件的定义Mercer 定理实际应用…

Kafka(三)Producer第二篇

一,生产者架构 生产者客户端由两个线程协调运行,分别为主线程和Sender线程(发送线程)。 主线程:KafkaProducer创建消息,通过拦截器、序列化器和分区器之后缓存到消息收集器RecordAccumulator中;…

Redis 中的跳跃表(Skiplist)基本介绍

Redis 中的跳跃表(Skiplist)是一种用于有序元素集合的快速查找数据结构。它通过一个多级索引来提高搜索效率,能够在对数时间复杂度内完成查找、插入和删除操作。跳跃表特别适用于实现有序集合(sorted set)的功能&#…

大语言模型的直接偏好优化(DPO)对齐在PAI-QuickStart实践

直接偏好优化(Direct Preference Optimization,DPO)算法是大语言模型对齐的经典算法之一,它巧妙地将奖励模型(Reward Model)训练和强化学习(RL)两个步骤合并成了一个,使得训练更加快…

MySQL 给数据表增加一列,一定会锁表吗?

在 MySQL 中,给数据表增加一列,是否会锁表取决于使用的存储引擎以及 MySQL 的版本。 InnoDB 存储引擎在 MySQL 之前的行为 之前版本的 MySQL 中,如果你使用 ALTER TABLE 命令来增加一列,对于使用 InnoDB 存储引擎的表&#xff0…

【算法】单调队列单调栈

一、单调队列 用来维护一段区间内的最大值或最小值,例如滑动窗口、区间最值等问题。 基本概念 单调队列是一种存储数据的队列,其中元素的顺序是单调递增或单调递减的。在算法竞赛中,我们一般使用两个单调队列,一个维护单调递增序…

【版面费优惠丨ACM独立出版丨接受全文摘要投稿】2024年生物医药和智能技术国际学术会议(ICBIT 2024,8月23-25)

“2024年生物医药和智能技术国际学术会议(ICBIT 2024)”拟定于2024年8月23-25日于珠海召开。近年来,智能技术已经逐渐走入生物医药领域,并在与生物医药领域的融合创新中凸显出巨大的发展潜力和社会价值。人工智能技术在生物医药领…

水处理基本知识

RO反渗透程序设计软件下载 水处理基本知识 纯水制备的核心工艺 核心工艺:纯水(超纯水)制备的主要处理工艺,结合前处理(预处理)工艺,辅助工艺及特殊工艺,组成完整的纯水制备工艺。结…

优质作品集秘诀:8个技巧让你的作品脱颖而出

制作一个高质量的投资组合不仅可以展示你的技能和创造力,还可以帮助你在求职和职业发展中脱颖而出。如何制作高质量的投资组合?今天给大家讲述作品集的 8 个实用技能,帮助你制作出令人印象深刻的作品集! 1、精选作品 并不是所有…

飞睿智能会议室静止雷达人体检测传感器,实时监测使用状态,有人、无人智能感应节能减

在这个科技日新月异的时代,每一个细微的创新都可能成为推动行业创新的关键力量。今天,让我们聚焦于一项看似不起眼却实则潜力无限的技术——飞睿智能静止雷达人体检测传感器,以及它在会议室这一商务交流核心区域中的巧妙应用。想象一下&#…

前端Canvas入门——怎么用Canvas画一些简单的图案

Canvas作为前端的画图工具&#xff0c;其实用途还是蛮广泛的&#xff0c;但是很多前端学习课程其实都很少涉及到这块内容。 于是乎&#xff0c;就写下这个了。 当然啦&#xff0c;目前还在学习摸索中。 一些实战代码&#xff0c;仅供参考&#xff1a; <canvasid"ctx&…

EtherCAT总线冗余让制造更安全更可靠更智能

冗余定义 什么是总线冗余功能&#xff1f;我们都知道&#xff0c;EtherCAT现场总线具有灵活的拓扑结构&#xff0c;设备间支持线型、星型、树型的连接方式&#xff0c;其中线型结构简单、传输效率高&#xff0c;大多数的现场应用中也是使用这种连接方式&#xff0c;如下图所示…

【Qt课设】基于Qt实现的中国象棋

一、摘 要 本报告讨论了中国象棋程序设计的关键技术和方法。首先介绍了中国象棋的棋盘制作&#xff0c;利用Qt中的一些绘画类的函数来进行绘制。在创作中国象棋棋子方面&#xff0c;首先&#xff0c;我们先定义一下棋子类&#xff0c;将棋子中相同的部分进行打包&#xff0c;使…

idea推送到gitee 401错误

在idea上推送时遇到这样的问题&#xff0c;解决方法如下&#xff1a; 在https://的后面加上 用户名:密码 然后再提交就ok啦&#xff01;

三、SpringMVC

三、SpringMVC 1、SpringMVC简介 1.1、什么是MVC MVC是一种软件架构的思想&#xff0c;将软件按照模型、视图、控制器来划分 M&#xff1a;Model&#xff0c;模型层&#xff0c;指工程中的JavaBean&#xff0c;作用是处理数据 JavaBean分为两类&#xff1a; 一类称为实体…

c语言实战-极简扫雷

C语言/c写的C语言实战项目扫雷 结构比较清晰&#xff0c;仅供参考&#xff1a; 核心是扫雷的递归算法实现 上代码: #include <stdio.h> #include <stdlib.h> #include <time.h>#define SIZE 10 #define MINES 15char board[SIZE][SIZE]; // 游戏棋盘// 初…