面向对象与设计模式第二课:设计模式实战
第三章:面向对象与设计模式
第二课:设计模式实战
设计模式是软件工程中的一项重要实践,它为解决常见的设计问题提供了经过验证的解决方案。本课将深入探讨几种常见的设计模式,并通过实际案例分析其在项目中的应用。
1. 每种设计模式的详尽解释与代码示例
设计模式分为三大类:创建型模式、结构型模式和行为型模式。以下是每种模式的详细解释与代码示例。
1.1 创建型模式
创建型模式专注于对象的创建过程,提供了创建对象的多种方式,降低了系统的复杂度。
1.1.1 单例模式
单例模式确保某个类仅有一个实例,并提供一个全局访问点。它非常适合于需要全局访问的对象,如配置管理器或数据库连接。
实现步骤:
- 将构造函数设为私有。
- 提供一个静态方法,用于获取单例实例。
- 在静态方法中检查实例是否存在,如果不存在,则创建一个。
代码示例:
class Singleton {
private:static Singleton* instance;// 私有构造函数,防止外部创建实例Singleton() {}public:static Singleton* getInstance() {if (!instance) {instance = new Singleton();}return instance;}void showMessage() {std::cout << "Hello from Singleton!" << std::endl;}
};// 初始化静态成员
Singleton* Singleton::instance = nullptr;
使用场景:
- 在应用程序中需要唯一实例的地方,例如日志记录、配置管理。
优缺点:
- 优点:控制实例数量,减少内存开销。
- 缺点:可能导致全局状态的问题,不利于单元测试。
实际应用: 在大型企业应用中,单例模式被广泛用于数据库连接池的管理,确保应用程序中的数据库连接都是通过一个管理实例来处理,从而提高资源的利用率和降低并发访问的问题。
扩展讨论: 为了确保线程安全,可以使用懒汉式或饿汉式的单例实现方法,或者使用std::call_once
来确保线程安全的实例创建。
1.1.2 工厂模式
工厂模式定义了一个接口,用于创建对象,但将具体实现推迟到子类中。它提供了一种封装对象创建的方式,使得客户端不需要了解具体的创建过程。
实现步骤:
- 定义一个产品接口。
- 创建具体的产品类实现该接口。
- 定义一个工厂类,用于创建具体产品的实例。
代码示例:
class Product {
public:virtual void use() = 0;
};class ConcreteProductA : public Product {
public:void use() override {std::cout << "Using Product A" << std::endl;}
};class ConcreteProductB : public Product {
public:void use() override {std::cout << "Using Product B" << std::endl;}
};class Creator {
public:virtual Product* factoryMethod() = 0;void someOperation() {Product* product = factoryMethod();product->use();}
};class ConcreteCreatorA : public Creator {
public:Product* factoryMethod() override {return new ConcreteProductA();}
};class ConcreteCreatorB : public Creator {
public:Product* factoryMethod() override {return new ConcreteProductB();}
};
使用场景:
- 在创建对象时,客户端无需知道具体的类,只需调用工厂方法。
优缺点:
- 优点:代码解耦,易于扩展。
- 缺点:增加了系统的复杂度。
实际应用: 在电商平台中,不同的支付方式(如信用卡、PayPal)可以使用工厂模式创建,使得添加新支付方式时,只需新增一个工厂类,而无需更改客户端代码。
扩展讨论: 工厂模式的变种,如抽象工厂模式,允许创建多个系列的产品,适用于复杂的对象创建场景。
1.2 结构型模式
结构型模式关注类和对象的组合,以形成更大的结构,常用的有适配器模式、装饰者模式等。
1.2.1 适配器模式
适配器模式允许将一个类的接口转换成客户端所期望的另一种接口,使得不兼容的接口能够协同工作。
实现步骤:
- 定义目标接口。
- 实现适配器类,内部持有被适配者的实例。
- 在适配器类中实现目标接口的方法,调用被适配者的方法。
代码示例:
class Target {
public:virtual void request() {std::cout << "Target request" << std::endl;}
};class Adaptee {
public:void specificRequest() {std::cout << "Specific request" << std::endl;}
};class Adapter : public Target {
private:Adaptee* adaptee;public:Adapter(Adaptee* a) : adaptee(a) {}void request() override {adaptee->specificRequest();}
};
使用场景:
- 当需要集成已有系统而无法修改其代码时,例如引入第三方库。
优缺点:
- 优点:提高了系统的灵活性。
- 缺点:增加了类的数量,可能导致系统复杂性提高。
实际应用: 在项目中,如果需要集成不同的第三方库(如支付接口),适配器模式可以帮助统一接口,使得调用方式一致,便于后期维护和更换。
扩展讨论: 适配器模式可以与装饰者模式结合使用,以同时实现接口适配和功能增强。
1.2.2 装饰者模式
装饰者模式允许动态地给一个对象添加一些额外的职责,提供比继承更灵活的扩展方式。
实现步骤:
- 定义一个组件接口。
- 创建具体的组件类实现该接口。
- 创建装饰者类,持有一个组件实例,并在其方法中添加功能。
代码示例:
class Component {
public:virtual std::string operation() {return "Base Component";}
};class Decorator : public Component {
protected:Component* component;public:Decorator(Component* c) : component(c) {}std::string operation() override {return component->operation() + " + Decorated";}
};
使用场景:
- 需要在运行时添加功能时,例如用户界面元素的动态装饰。
优缺点:
- 优点:增强了系统的灵活性和可扩展性。
- 缺点:增加了复杂度,可能导致过多的小类。
实际应用: 在GUI框架中,可以使用装饰者模式为按钮添加边框、阴影等效果,而无需创建多个子类。
扩展讨论: 装饰者模式与策略模式的结合可以实现功能的多样化,通过不同的装饰组合,产生不同的行为。
1.3 行为型模式
行为型模式主要关注对象之间的交互和职责分配,常见的有策略模式、观察者模式等。
1.3.1 策略模式
策略模式定义了一系列算法,并将每一个算法封装起来,使它们可以互换使用。
实现步骤:
- 定义一个策略接口。
- 实现多个具体策略类。
- 定义上下文类,持有一个策略实例,并在运行时根据需要选择策略。
代码示例:
class Strategy {
public:virtual void algorithm() = 0;
};class ConcreteStrategyA : public Strategy {
public:void algorithm() override {std::cout << "Algorithm A" << std::endl;}
};class ConcreteStrategyB : public Strategy {
public:void algorithm() override {std::cout << "Algorithm B" << std::endl;}
};class Context {
private:Strategy* strategy;public:Context(Strategy* s) : strategy(s) {}void executeStrategy() {strategy->algorithm();}
};
使用场景:
- 需要在运行时选择算法的情况,例如排序算法、压缩算法。
优缺点:
- 优点:提高了代码的灵活性和可扩展性。
- 缺点:客户端必须了解所有策略的类。
实际应用: 在图像处理应用中,可以根据用户的选择使用不同的图像压缩算法,而无需修改核心业务逻辑。
扩展讨论: 策略模式可以与工厂模式结合使用,根据不同条件动态选择策略。
2. 实际项目中的设计模式应用案例
通过具体项目的分析,进一步了解设计模式如何提高代码质量和开发效率。
2.1 电子商务平台中的应用
在电子商务平台中,设计模式可以帮助解决复杂的业务需求,提高代码的可维护性。
- 使用单例模式:保证配置管理和数据库连接的唯一性。
- 使用工厂模式:根据用户的选择创建不同的支付方式。
- 使用策略模式:根据用户的身份(如普通用户、VIP用户)提供不同的折扣策略。
2.2 游戏开发中的应用
在游戏开发中,设计模式的应用同样重要,能够有效管理复杂的游戏逻辑。
- 使用观察者模式:实现游戏中的事件系统,允许多个对象响应游戏事件。
- 使用状态模式:管理角色的不同状态(如行走、攻击、休息),使得状态之间的转换清晰可控。
2.3 企业级应用中的应用
在大型企业应用中,设计模式可以帮助应对日益复杂的业务需求。
- 使用适配器模式:集成不同的外部API,提供统一的接口。
- 使用装饰者模式:动态地给业务对象添加功能,例如为报告生成器添加过滤器。
3. 设计模式与代码重构的结合
设计模式不仅仅是解决问题的工具,更是进行代码重构的重要手段。通过将设计模式引入现有代码,可以提升代码的结构和可读性。
3.1 识别重构的必要性
在代码重构之前,首先需要识别出代码中的“坏味道”,例如:
- 过长的函数。
- 重复代码。
- 难以理解的类设计。
3.2 引入设计模式
在进行重构时,可以考虑引入适合的设计模式来优化代码结构。对于每个“坏味道”,选择合适的模式进行修复。例如:
- 对于重复代码,可以考虑使用模板方法模式。
- 对于过长的函数,可以使用策略模式,将逻辑拆分为不同的策略。
3.3 重构过程
实施重构时,应确保每个修改都有相关的单元测试,以避免引入新问题。重构应遵循小步快跑的原则,每次只进行小幅修改,确保系统稳定性。
3.4 测试与验证
重构完成后,运行测试用例验证系统的正确性。通过测试,确保新引入的设计模式未破坏现有功能。
总结
本课详细分析了多种设计模式及其在实际项目中的应用,强调了设计模式在提高代码质量和可维护性方面的重要性。通过掌握设计模式,开发者可以在设计和重构代码时,做出更为明智的决策。
相关文章:

面向对象与设计模式第二课:设计模式实战
第三章:面向对象与设计模式 第二课:设计模式实战 设计模式是软件工程中的一项重要实践,它为解决常见的设计问题提供了经过验证的解决方案。本课将深入探讨几种常见的设计模式,并通过实际案例分析其在项目中的应用。 1. 每种设计…...

非科班出身如何转行程序员?
非科班出身是指那些大学专业为非计算机相关专业的人群,多数人对于计算机基础了解比较少,甚至零基础。这部分人群中有相当多一部分处于对于编程的兴趣和外界了解的印象想转行成为一名程序员。 非科班出身与计算机科班出身相比有着天然的劣势,在…...

多台NFS客户端访问一台nfs服务器
目录 1.安装服务 2.创建用户和用户组 3.写配置文件 (服务端) 4.创建/share目录 5.挂载服务(在两个服务端上) 6.测试 1.安装服务 yum -y install rpcbind nfs 2.创建用户和用户组 useradd -u 555 nfs-share groupadd -u 556 nfs-share …...

【STM32 HAL库】MPU6050姿态解算 卡尔曼滤波
【STM32 HAL库】MPU6050姿态解算 卡尔曼滤波 前言MPU6050寄存器代码详解mpu6050.cmpu6050.h 使用说明 前言 本篇文章基于卡尔曼滤波的原理详解与公式推导,来详细的解释下如何使用卡尔曼滤波来解算MPU6050的姿态 参考资料:Github_mpu6050 MPU6050寄存器…...

Linux系统——ssh远程连接
Linux系统——ssh远程连接 一、ssh协议介绍1、远程连接协议2、ssh服务基本操作3、ssh常用操作 二、ssh加密1、加密算法类型2、对称加密算法3、非对称加密算法 三、免密ssh的配置1、ssh认证方式2、配置免密ssh3、ssh-copy-id做了什么? 四、ssh服务配置 一、ssh协议介…...

python学习-第一个小游戏(vscode环境)
学习小甲鱼的视频,写了一个小游戏,vscode环境 运行结果 源码地址: python小游戏-猜数字源码...

程序设计基础I-单元测试2(机测)
7-1 sdut-C语言实验-AB for Input-Output Practice (不确定次数循环) Your task is to Calculate a b. Too easy?! Of course! I specially designed the problem for all beginners. You must have found that some problems have the same titles with this one, yes, a…...

Claude 3.5深夜觉醒,学会模仿人类用电脑,力压GPT-4o
1.Claude 3.5深夜重磅更新 Anthropic AI深夜发布了备受期待的Claude 3.5系列更新,包括了全新升级的Claude 3.5 Sonnet和首发的Claude 3.5 Haiku。 虽然备受期待的Opus版本尚未公布,但新版本的Sonnet在推理能力上取得了显著的进步,超越了Open…...

PuTTY
PuTTY 是一个免费的开源终端仿真器和串口终端,广泛用于在 Windows 系统上进行 SSH、Telnet 和 Rlogin 等网络协议的连接。 它允许用户通过安全的方式访问远程计算机,常用于管理服务器和网络设备。 PuTTY 也支持公钥身份验证和端口转发等功能,…...

2024软件测试面试秘籍(含答案+文档)
🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 Part1 1、你的测试职业发展是什么? 测试经验越多,测试能力越高。所以我的职业发展是需要时间积累的,一步步向着高级测试工程师…...

券商api怎么获取,如何获取券商API接口?
炒股自动化:申请官方API接口,散户也可以 python炒股自动化(0),申请券商API接口 python炒股自动化(1),量化交易接口区别 Python炒股自动化(2):获取…...

跟着六西格玛设计DFSS走,让你的项目、服务、产品都“牛”起来——张驰咨询
六西格玛设计,这一数据驱动的质量管理策略,正以其独特的魅力和广泛的适用性,在各行各业中掀起了一场质量革命。从精密的制造业到细致的服务业,再到复杂的项目管理,六西格玛设计以其严谨的逻辑和高效的方法,…...

【2024.10.22练习】机器人塔
题目描述 题目分析 由于数据小,直接考虑DFS搜索底层所有排列组合。 我的代码 需要注意:这个数据有点漏洞的是题干声明NM<231,但实际上有个测试点是等于231的。 一开始在build_tower()函数中建完整个塔再判定是否…...

酒店预订订房小程序源码系统 多酒店入驻+打造类似美团的酒店模式 带完整的安装代码包以及搭建部署教程
系统概述 随着移动互联网的普及,小程序因其轻量级、无需下载安装、即用即走的特点,迅速成为各行业的标配。对于酒店预订行业而言,小程序不仅能够有效提升用户体验,还能降低运营成本,提高转化率。本源码系统正是基于这…...

springboot037基于SpringBoot的墙绘产品展示交易平台的设计与实现(论文+源码)_kaic
毕 业 设 计(论 文) 题目:墙绘产品展示交易平台设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本墙绘产品展示…...

YOLOv8实战人脸-口罩检测与识别【数据集+YOLOv8模型+源码+PyQt5界面】
本文采用YOLOv8作为核心算法框架,结合PyQt5构建用户界面,使用Python3进行开发。YOLOv8以其高效的实时检测能力,在多个目标检测任务中展现出卓越性能。本研究针对人脸-口罩数据集进行训练和优化,该数据集包含丰富的人脸-口罩图像样…...

《黑神话悟空》各章节boss顺序汇总
第一章BOSS顺序: 1、牯护院:犀牛精,位于苍狼岭娟,击败后能获得定身术。 2、广智:火刀狼, 位于观音禅院,击败后获得广智变身,记得敲钟。 3、蓝皮幽魂:蓝皮大头࿰…...

rust中cargo.toml详细介绍
1. cargo.toml介绍 Cargo.toml是 Rust 项目的配置文件,它使用 TOML(Tom’s Obvious, Minimal Language)格式。 1.1 基本结构 [package]:包含项目的基本信息。 name:项目名称。version:项目版本号。edition:Rust 版本,如 2018、2021 等。[package]name = "abc&q…...

jupyter notebook 笔记
nbclassic 经典版 新版的 jupyter notebook 太丑了。 最难受的是字体太小了。 我还是喜欢老版本的 jupyter notebook. 安装经典版: pip install nbclassic 启动经典版: jupyter server 或是 jupyter nbclassic 参考来源: https://github.com/jupyter/nbclassic jupyter note…...

Atlas800昇腾服务器(型号:3000)—CANN安装(二)
服务器配置如下: CPU/NPU:鲲鹏 CPU(ARM64)A300I pro推理卡 系统:Kylin V10 SP1【下载链接】【安装链接】 驱动与固件版本版本: Ascend-hdk-310p-npu-driver_23.0.1_linux-aarch64.run【下载链接】 Ascend-…...

考研鼓励小程序
考研冲刺倒计时,加入我们一起奋斗💥 考研倒计时提醒神器来啦! 距离考研越来越近,复习是否紧张又有些焦虑?不用担心!我特别制作了一个 考研倒计时提醒服务,每天在 7:00 和 23:59 准时为你发送倒…...

Wooden UI(木头UI纹理按钮边框 背景图标 带PNG素材)
资源包包含以下元素:按钮、图标、框架、复选框等,提供分层的 PSD 文件。 下载:Unity资源商店链接资源下载链接 效果图:...

WebRTC音频 03 - 实时通信框架
WebRTC音频01 - 设备管理 WebRTC音频 02 - Windows平台设备管理 WebRTC音频 03 - 实时通信框架(本文) WebRTC音频 04 - 关键类 WebRTC音频 05 - 音频采集编码 一、前言: 前面介绍了音频设备管理,并且以windows平台为例子,介绍了ADM相关的类…...

Maven陷阱揭秘:避开Java项目构建的10大常见误区
文章目录 引言基础知识核心概念示例演示实际应用深入与最佳实践常见问题解答结语学习资源互动环节 引言 Maven是Java项目中广泛使用的项目管理和构建自动化工具。它通过一个中央仓库和依赖管理系统,简化了项目的构建和依赖管理。理解Maven的依赖机制对于构建和维护…...

基础数据结构思路写法记录,便于回顾
重思路非代码。基础的思路搞懂了,变形题目顺着思考基本都能写出来! 二分查找 int binarySearch(vector<int> &nums, int target) {// write your code hereif (nums.empty()) {return -1;}int start 0;int end nums.size() - 1;while (star…...

基于AI的量化投资框架Qlib的Python依赖包pyqlib安装问题记录
版权声明:本文为博主原创文章,如需转载请贴上原博文链接:基于AI的量化投资框架Qlib的Python依赖包pyqlib安装问题记录-CSDN博客 前言:最近想使用Qlib来做量化交易的策略研究,但是第一步就卡在了安装pyqlib依赖包&#…...

《语音识别方案选择》
《语音识别方案选择》 一、引言二、语音识别技术概述(一)语音识别的基本原理(二)语音识别技术的发展历程(三)语音识别技术的分类1、基于声学模型的语音识别2、基于语言模型的语音识别3、端到端的语音识别 三…...
目标检测数据集图片及标签同步裁剪
目录 前言 具体方法 使用介绍 完整代码 前言 在目标检测任务中,模型的训练依赖于大量高质量的标注数据。然而,获取足够多的标注数据集往往代价高昂,并且某些情况下,数据集中的样本分布不均衡,这会导致模型的泛化能…...

【设计模式-简单工厂】
定义 简单工厂模式(Simple Factory Pattern)是一种创建型设计模式,用于通过一个工厂类来创建某个产品类的实例,而不直接在客户端(调用方)中实例化对象。 这种模式的主要思想是将对象的创建逻辑集中在一个…...

多个版本的GCC(GNU编译器集合)可以同时安装并存
在Ubuntu系统中,多个版本的GCC(GNU编译器集合)可以同时安装并存。GCC是编译C、C以及其他编程语言程序的重要工具,不同的项目可能需要不同版本的GCC来确保兼容性。 为什么需要多个GCC版本 项目依赖:不同的软件项目可能…...