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

设计模式学习思路二

        设计模式的学习思路_设计模式必须按顺序进行吗-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. 确定模式时的思考步骤 以下是分析代码时&#xff0c;你可以遵循的一些思路和步骤&#xff0c;帮助你识别可能使用的设计模式&#xff1a; a. 识别…...

什么是等级保护

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

k8s api对象,CRD

在Kubernetes项目中&#xff0c;一个API对象在Etcd里的完整资源路径&#xff0c;是由&#xff1a;Group&#xff08;API组&#xff09;、Version&#xff08;API版本&#xff09;和Resource&#xff08;API资源类型&#xff09;三个部分组成 apiVersion: batch/v2alpha1 kind:…...

【C++指南】C++内存管理 深度解析

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《C指南》 期待您的关注 目录 引言 一、C 内存管理概述 二、C内存区域划分 三、C 内存管理方式 &#x1f343;1.自动内存管理…...

C++小碗菜之二:软件单元测试

“没有测试的代码重构不能称之为重构&#xff0c;它仅仅是垃圾代码的到处移动” ——Corey Haines 目录 前言 什么是单元测试&#xff1f; 单元测试的组成 单元测试的命名 单元测试的独立性 Google Test 单元测试的环境配置与使用 1. Ubuntu下安装 Google Test 2. 编写…...

PyCharm+Selenium+Pytest配置小记

1、下载ChromeDriver&#xff1a; Chrome130以后的Driver下载&#xff1a; Chrome for Testing availabilityhttps://googlechromelabs.github.io/chrome-for-testing/ &#xff08;1&#xff09;查看自己Crome浏览器的版本&#xff1a;设置-->关于 Chrome&#xff1b; &…...

摩尔线程 国产显卡 MUSA 并行编程 学习笔记-2024/12/04

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

【FAQ】HarmonyOS SDK 闭源开放能力 —Remote Communication Kit

1.问题描述&#xff1a; DynamicDnsRule有没有示例&#xff1f;这个地址是怎么解析出来 https://developer.huawei.com/consumer/cn/doc/harmonyos-references/remote-communication-rcp-0000001770911890#section8160554134811 解决方案&#xff1a; ‘DynamicDnsRule’&a…...

【日常记录-Mybatis】PageHelper导致语句截断

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

随时随地掌控数据:如何使用手机APP远程访问飞牛云NAS

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

JVM 类加载器有哪些?双亲委派机制的作用是什么?如何自定义类加载器?

类加载器分类 大家好&#xff0c;我是码哥&#xff0c;可以叫我靓仔&#xff0c;《Redis 高手心法》畅销书作者。 先回顾下&#xff0c;在 Java 中&#xff0c;类的初始化分为几个阶段: 加载、链接&#xff08;包括验证、准备和解析&#xff09;和 初始化。 而 类加载器&#x…...

从基态到激发态再到里德伯态的双光子激发过程

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

Clickhouse 外部存储引擎

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

eclipse怎么配置jdk路径?

在Eclipse中配置JDK路径是一个简单的步骤&#xff0c;以下是配置JDK路径的步骤&#xff1a; 打开Eclipse&#xff1a;启动Eclipse IDE。 访问首选项&#xff1a; 在Eclipse的菜单栏中&#xff0c;选择 Window > Preferences&#xff08;对于Mac OS X用户&#xff0c;选择 E…...

【前端】JavaScript 中的创建对象模式要点

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

GWAS分析先做后学

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

【系统设计】高可用之缓存基础

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

《Java核心技术I》volatile字段

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

2024运维故障记 | 12/2 网易云音乐崩了

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

架构设计读后——微服务

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

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...