设计模式学习思路二
设计模式的学习思路_设计模式必须按顺序进行吗-CSDN博客
以下是一些方法和思路可以帮助你更清晰地识别使用了哪种设计模式。
1. 确定模式时的思考步骤
以下是分析代码时,你可以遵循的一些思路和步骤,帮助你识别可能使用的设计模式:
a. 识别类和对象的角色
首先,看看类和对象在系统中扮演的角色。这是识别设计模式的关键线索,因为每种设计模式都有其特定的角色。
- 职责:每个类或对象的职责是什么?是否有一些类在做某些任务时将功能分配给其他类,或在某些情况下改动自己的行为?
- 状态和行为的关系:某个类的行为是否会随着对象的状态变化而改变?
- 对象间的协作:多个类之间是如何交互的?是否存在某种统一的接口来简化多种操作?
b. 查看类之间的关系
很多设计模式的核心就在于类与类之间的关系,了解类的继承、组合和接口实现关系,有助于识别模式。
- 继承和接口:是否有类通过继承或接口实现一些功能,以便于扩展或改变行为?
- 组合关系:是否通过对象组合(而非继承)来实现灵活的功能模块?
- 工厂方法:是否有工厂类来创建对象,而不是直接在代码中new对象?
c. 是否有灵活的扩展和变化机制
许多设计模式都具有很强的扩展性,关注代码中是否有容易扩展、变化的机制:
- 开闭原则:是否有部分代码设计成可以很容易添加新功能(开闭原则),比如使用接口或抽象类来隔离变化?
- 灵活切换或变化的策略:代码是否允许在运行时或编译时改变某些行为(比如策略模式、状态模式等)?
2. 常见设计模式的识别方法
以下是一些常见设计模式的识别方法,帮助你快速分析代码中的模式:
1. 工厂方法模式(Factory Method)
- 识别方法:查看代码是否存在工厂方法或工厂类,通常会有一个方法负责创建不同类型的对象,而不是直接 new 对象。
- 例子:如果你看到一个抽象类或接口提供一个方法 createProduct(),而具体的实现类通过继承或实现该接口来决定具体创建哪种产品,那么很可能使用了工厂方法模式。
class Product {
public:virtual void doSomething() = 0;
};class ConcreteProductA : public Product {
public:void doSomething() override {std::cout << "Product A" << std::endl;}
};class Creator {
public:virtual Product* factoryMethod() = 0;
};class ConcreteCreatorA : public Creator {
public:Product* factoryMethod() override {return new ConcreteProductA();}
};
2. 单例模式(Singleton)
- 识别方法:检查是否有类的构造函数被隐藏(私有),并且是否有一个静态方法来返回该类的唯一实例。如果一个类只允许存在一个实例并提供全局访问点,那么可能是单例模式。
- 例子:类中有一个私有静态成员变量 instance,并且提供一个静态方法 getInstance() 返回唯一实例。
class Singleton {
private:static Singleton* instance;Singleton() {}public:static Singleton* getInstance() {if (!instance) {instance = new Singleton();}return instance;}
};
3. 观察者模式(Observer)
- 识别方法:查看是否有一个主体类(被观察者),它的状态变化会通知多个观察者类。通常会看到主体类维护一个观察者列表,状态变化时调用每个观察者的更新方法。
- 例子:如果一个类通过 addObserver()、removeObserver() 来管理一组观察者,并且状态变化时通知这些观察者,那么很可能是观察者模式。
class Subject {
private:std::vector<Observer*> observers;public:void addObserver(Observer* observer) {observers.push_back(observer);}void notifyObservers() {for (auto observer : observers) {observer->update();}}
};
4. 策略模式(Strategy)
- 识别方法:如果你看到不同的类(策略)实现同一接口,并且上下文类(通常有一个 setStrategy() 方法)会在运行时根据不同情况切换策略,那么可能是策略模式。
- 例子:策略模式允许行为在运行时发生变化,你通常会看到一个上下文类和多个策略类(实现相同接口)。
class Strategy {
public:virtual void execute() = 0;
};class ConcreteStrategyA : public Strategy {
public:void execute() override {std::cout << "Strategy A" << std::endl;}
};class Context {
private:Strategy* strategy;public:void setStrategy(Strategy* strategy) {this->strategy = strategy;}void executeStrategy() {strategy->execute();}
};
5. 状态模式(State)
- 识别方法:观察对象的行为是否会根据其内部状态发生变化,通常会看到一个状态接口,并且有多个具体的状态类实现不同的行为。上下文类会持有一个状态对象,并根据需要改变它。
- 例子:状态模式允许对象的行为在不同的状态下变化,通常通过上下文类来委托状态的变化。
class State {
public:virtual void handle() = 0;
};class ConcreteStateA : public State {
public:void handle() override {std::cout << "State A" << std::endl;}
};class Context {
private:State* state;public:void setState(State* state) {this->state = state;}void request() {state->handle();}
};
6. 外观模式(Facade)
- 识别方法:如果代码中有一个外观类,它将多个子系统的功能封装在一个简单的接口中,通常这种模式下会看到一个简化的接口暴露给外部调用者。
- 例子:外观模式封装了复杂的子系统行为,通过一个外观类来提供简化的接口,避免客户端直接与多个子系统交互。
class SubsystemA {
public:void operationA() {std::cout << "Subsystem A operation" << std::endl;}
};class Facade {
private:SubsystemA subsystemA;public:void simplifiedOperation() {subsystemA.operationA();}
};
3. 常见模式的相似点与区分
有些设计模式看起来相似,尤其是它们的目标都是封装和简化复杂系统。以下是一些常见模式的相似点与区分方法:
- 外观模式 vs. 代理模式:
- 外观模式将多个复杂子系统的接口统一化,简化对复杂系统的访问。
- 代理模式是对某个对象的控制,它通过代理对象来控制对真实对象的访问。
- 区别:外观模式主要是简化对系统的使用,而代理模式是通过控制访问来实现某种额外的功能(如懒加载、权限控制等)。
- 状态模式 vs. 策略模式:
- 状态模式和策略模式都依赖于封装变化的行为。
- 区别:状态模式侧重于根据对象的内部状态来改变行为,而策略模式侧重于通过上下文类选择不同的策略来改变行为。
- 模板方法模式 vs. 策略模式:
- 都是将某些行为提取成可以变化的部分。
- 区别:模板方法模式是通过定义算法框架并留出钩子方法供子类实现,而策略模式是通过上下文类在运行时切换不同的策略。
4. 总结
通过了解不同设计模式的意图、角色和结构,你可以在代码中识别出对应的模式。关键是关注代码的职责划分、类之间的关系、行为的变化和灵活扩展的机制。
相关文章:

设计模式学习思路二
设计模式的学习思路_设计模式必须按顺序进行吗-CSDN博客 以下是一些方法和思路可以帮助你更清晰地识别使用了哪种设计模式。 1. 确定模式时的思考步骤 以下是分析代码时,你可以遵循的一些思路和步骤,帮助你识别可能使用的设计模式: a. 识别…...

什么是等级保护
1.为什么要实施等级保护: •国家信息安全形势严峻(敌对势力),针对基础信息系统的违法犯罪持续上升(网上诈骗、入侵、网上盗窃) •维护国家安全的需求(基础信息网络【互联网、电信网、广电网】及重要信息系统【银行、铁路、电力、海关】已经成为国家的关键基础设施) •信息安全是…...

k8s api对象,CRD
在Kubernetes项目中,一个API对象在Etcd里的完整资源路径,是由:Group(API组)、Version(API版本)和Resource(API资源类型)三个部分组成 apiVersion: batch/v2alpha1 kind:…...

【C++指南】C++内存管理 深度解析
💓 博客主页:倔强的石头的CSDN主页 📝Gitee主页:倔强的石头的gitee主页 ⏩ 文章专栏:《C指南》 期待您的关注 目录 引言 一、C 内存管理概述 二、C内存区域划分 三、C 内存管理方式 🍃1.自动内存管理…...

C++小碗菜之二:软件单元测试
“没有测试的代码重构不能称之为重构,它仅仅是垃圾代码的到处移动” ——Corey Haines 目录 前言 什么是单元测试? 单元测试的组成 单元测试的命名 单元测试的独立性 Google Test 单元测试的环境配置与使用 1. Ubuntu下安装 Google Test 2. 编写…...

PyCharm+Selenium+Pytest配置小记
1、下载ChromeDriver: Chrome130以后的Driver下载: Chrome for Testing availabilityhttps://googlechromelabs.github.io/chrome-for-testing/ (1)查看自己Crome浏览器的版本:设置-->关于 Chrome; &…...

摩尔线程 国产显卡 MUSA 并行编程 学习笔记-2024/12/04
Learning Roadmap: Section 1: Intro to Parallel Programming & MUSA Deep Learning Ecosystem(摩尔线程 国产显卡 MUSA 并行编程 学习笔记-2024/11/30-CSDN博客)UbuntuDriverToolkitcondapytorchtorch_musa环境安装(2024/11/24-Ubunt…...

【FAQ】HarmonyOS SDK 闭源开放能力 —Remote Communication Kit
1.问题描述: DynamicDnsRule有没有示例?这个地址是怎么解析出来 https://developer.huawei.com/consumer/cn/doc/harmonyos-references/remote-communication-rcp-0000001770911890#section8160554134811 解决方案: ‘DynamicDnsRule’&a…...

【日常记录-Mybatis】PageHelper导致语句截断
1. 简介 PageHelper是Mybatis-Plus中的一个插件,主要用于实现数据库的分页查询功能。其核心原理是将传入的页码和条数赋值给一个Page对象,并保存到本地线程ThreadLocal中,接下来,PageHelper会进入Mybatis的拦截器环节,…...

随时随地掌控数据:如何使用手机APP远程访问飞牛云NAS
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

JVM 类加载器有哪些?双亲委派机制的作用是什么?如何自定义类加载器?
类加载器分类 大家好,我是码哥,可以叫我靓仔,《Redis 高手心法》畅销书作者。 先回顾下,在 Java 中,类的初始化分为几个阶段: 加载、链接(包括验证、准备和解析)和 初始化。 而 类加载器&#x…...

从基态到激发态再到里德伯态的双光子激发过程
铯原子(Cs)从基态6S1/2到激发态6P3/2再到里德伯态44D5/2的双光子激发过程, 并通过数值计算和图形化展示来研究不同失谐条件下的拉比频率、AC Stark位移差以及散射概率的变化 结果显示,在给定的实验参数下,拉比频率较低…...

Clickhouse 外部存储引擎
文章目录 外部存储引擎分类MySQL引擎PostgreSQL引擎MongoDB引擎JDBC引擎ODBC引擎Kafka引擎RabbitMQ引擎File引擎URL引擎HDFS引擎 外部存储引擎分类 引擎类型描述特点MySQL从 MySQL 数据库中读取数据用于与 MySQL 数据库共享数据,支持读取 MySQL 表中的数据 支持 SQ…...

eclipse怎么配置jdk路径?
在Eclipse中配置JDK路径是一个简单的步骤,以下是配置JDK路径的步骤: 打开Eclipse:启动Eclipse IDE。 访问首选项: 在Eclipse的菜单栏中,选择 Window > Preferences(对于Mac OS X用户,选择 E…...

【前端】JavaScript 中的创建对象模式要点
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: 前端 文章目录 💯前言💯对象属性值中的引号规则💯对象属性换行与尾随逗号的使用💯工厂模式:灵活高效的对象创建💯自定义构造函数:通过…...

GWAS分析先做后学
大家好,我是邓飞。 GWAS分析是生物信息和统计学的交叉学科,上可以学习编程,下可以学习统计。对于Linux系统,R语言,作图,统计学,机器学习等方向,都是一个极好的入门项目。生物信息如…...

【系统设计】高可用之缓存基础
缓存的缘起 使用缓存的主要原因包括提高系统性能、降低数据库负载、提升用户体验和保证系统可用性。 在计算机体系结构中,由于处理器和存储器的处理时间不匹配,在处理器和一个较大较慢的设备之间插入一个更小更快的存储设备(如高速缓存&a…...

《Java核心技术I》volatile字段
volatile字段 有多处理器的计算机能够暂时在寄存器或本地内存缓存中保存内存值,其结果是,运行在不同处理器上的线程可能看到同一个内存位置上有不同的值。编译器可以改变指令执行的顺序以使吞吐量更大化,编译器不会选择可能改变代码语义的顺…...

2024运维故障记 | 12/2 网易云音乐崩了
#运维故障记# 前两天看到网易云音乐崩了的新闻,回想了一下,今年从网易云音乐到支付宝、还有微软,近期就发生了好几起运维届的故障。 今年来不及计数了,先做个记录。 明年看看运维届的大故障会发生多少,什么原因&…...

架构设计读后——微服务
1 微服务历史 2005年:Dr. Peter Rodgers提出"Micro-Web-Services"概念2011年:一个软件架构工作组使用"microservice"来描述一中架构模式2012年;这个工作组正式使用"microservice"来代表这个架构2012年&#x…...

软考高级架构-9.4.4-双机热备技术 与 服务器集群技术
一、双机热备 1、特点: 软硬件结合:系统由两台服务器(主机和备机)、一个共享存储(通常为磁盘阵列柜)、以及双机热备软件(提供心跳检测、故障转移和资源管理功能的核心软件)组成。 …...

聊聊前端工程化
深度解析前端工程化 近年来,随着前端技术的快速迭代和项目复杂度的增加,前端开发已经从简单的页面搭建演变为专业的工程化体系。前端工程化通过工具链、标准化和流程化手段,不仅提高了开发效率,也大幅提升了项目的可维护性和协…...

“放弃Redis Desktop Manager使用Redis Insight”:日常使用教程(Redis可视化工具)
文章目录 更新Redis Insight连接页面基础解释自动更新key汉化暂时没有找到方法, Redis Desktop Manager在连接上右键在数据库上右键在key上右键1、添加连接2、key过期时间 参考文章 更新 (TωT)ノ~~~ βyё βyё~ 现在在维护另一…...

mmdection配置-yolo转coco
基础配置看我的mmsegmentation。 也可以参考b站 :https://www.bilibili.com/video/BV1xA4m1c7H8/?vd_source701421543dabde010814d3f9ea6917f6#reply248829735200 这里面最大的坑就是配置coco数据集。我一般是用yolo,这个yolo转coco格式很难搞定&#…...

聚合支付系统/官方个人免签系统/三方支付系统稳定安全高并发 附教程
聚合支付系统/官方个人免签系统/三方支付系统稳定安全高并发 附教程 系统采用FastAdmin框架独立全新开发,安全稳定,系统支持代理、商户、码商等业务逻辑。 针对最近一些JD,TB等业务定制,子账号业务逻辑API 非常详细,方便内置…...

力扣67. 二进制求和
给你两个二进制字符串 a 和 b ,以二进制字符串的形式返回它们的和。 示例 1: 输入:a "11", b "1" 输出:"100" 示例 2: 输入:a "1010", b "1011" 输出&#…...

网络安全中的 SOC 是什么?
当今世界,网络威胁日益增多,确保网络安全已成为各种规模企业的首要任务。网络安全讨论中经常出现的一个术语是 SOC,即安全运营中心的缩写。但网络安全中的 SOC 是什么呢? SOC在防御网络威胁、管理安全事件和全天候监控系统方面发…...

16、鸿蒙学习——Visibility与(if...else)该如何选择
在鸿蒙中我们如果要控制一个组件的显示与隐藏可以设置组件的Visibility属性,也可使用(if...else)条件控制,具体我们该选择哪个?二者有什么区别呢? 1、Visibility 名称描述Hidden隐藏,但参与布局…...

PH热榜 | 2024-12-05
1. Oopsie 标语:用AI和会话回放调试Flutter和React Native应用 介绍:Zipy推出的Oopsie是一款你唯一需要的AI赋能移动端调试工具,它能提供▶️会话回放、🤖错误监控、💡AI生成的概要分析,以及🔥…...

Qt Chart 模块化封装曲线图
一 版本说明 二 完成示例 此文章包含:曲线轴设置,曲线切换,单条曲线显示,坐标轴。。。 三 曲线图UI创建 在UI界面拖放一个QWidget,然后在 Widget里面放一个 graphicsView 四 代码介绍 1 头文件 #include <QString> #include <QTimer> #include <QMessa…...