摘要: 一、什么是目标? 目标是团队或项目希望实现的最终结果,它应具备以下特点: 清晰性:目标应明确、具体,能够被所有参与者理解。 价值导向:目标应为用户或客户提供明确的价值。 可衡量性:目标应有明确的验收条件,能够衡量是否达成。 二、如何定义目标? 方法1:电梯三分钟演讲法 提炼核心价值:通过三分钟演讲, 阅读全文
posted @ 2025-01-17 19:41 荣-- 阅读(49) 评论(0) 推荐(0) 编辑
摘要: 一、编码前的重构思考 在编码前,通过以下步骤审视接口和设计,确保代码的可维护性和可测试性: 站在单元测试的角度审视接口: 思考是否需要将所有public和protected函数都暴露出来。 考虑是否违反正交性原则,避免函数过于复杂或依赖过多。 避免将不同场景的代码混在一起,确保代码的可测试性。 放置 阅读全文
posted @ 2025-01-17 19:34 荣-- 阅读(30) 评论(0) 推荐(0) 编辑
摘要: 我的重构经历:编写代码生成器 概述 背景 多年前,我开发了一个基于C#的Windows程序——代码生成器,并在此后十多年间持续优化。该程序能够根据数据库表结构生成代码,并将结果显示在文本框中。最初是从同事那里接手的一个简单项目,经过不断扩展和重构,最终实现了通过数据库自动生成具备完整增删改查功能的网 阅读全文
posted @ 2025-01-17 19:11 荣-- 阅读(150) 评论(1) 推荐(0) 编辑
摘要: 当开发人员接到新任务后 1. 向上追溯(纵向拉齐) 1.1 首先提出的问题 这个任务针对的需求点是什么? 用户/客户是谁?他们有什么特点? 该需求为用户/客户提供了什么价值? 这个需求的满意条件是什么? 1.2 其次想到的是 这个需求属于哪个发布版本? 为什么这个版本需要开发这个需求? 这个版本的满 阅读全文
posted @ 2025-01-17 19:08 荣-- 阅读(435) 评论(6) 推荐(4) 编辑
摘要: 在软件开发过程中,单元测试代码不仅是测试工具,更是开发的重要辅助手段,如同IDE一样,帮助我们更高效地开发。本文将探讨单元测试的重要性、最佳实践以及常见误区。 1. 单元测试的最佳时机 单元测试的最佳编写时机是在第一个接口函数完成后立即开始。如果等到代码量庞大后再着手,往往会因为工作量过大而失去动力 阅读全文
posted @ 2017-08-24 12:43 荣-- 阅读(441) 评论(0) 推荐(1) 编辑

1. 软件设计中的坏味道(对应原书第7章)

核心理解:

  • 抽象不足:业务代码中掺杂过多细节,导致代码僵化、脆弱、难以理解和维护。
  • 业务逻辑应调用功能,而非实现功能:业务逻辑应通过调用功能接口来完成,而不是直接实现功能细节。
  • 功能抽象为接口,业务逻辑组合接口:功能应抽象为接口,业务逻辑通过组合和调度这些接口来实现。
  • 接口可扩展但不可修改:接口应保持稳定,允许扩展但不允许修改。
  • 功能实现可变,接口不可变:功能的实现可以灵活变化,但接口应保持稳定。
  • 优先调用库而非原始实现:尽量使用通用库(如STL、Boost),避免重复造轮子。

坏味道分类:

  1. 僵化性:设计难以修改,单一改动可能引发依赖模块的连锁反应。
    • 表现:实际工作量超出预期,未预料到的关联改动。
  2. 脆弱性:设计易于破坏,一个改动可能导致多个地方出现问题。
  3. 顽固性:设计难以重用,重用部分需要巨大努力和风险。
  4. 粘滞性:难以做正确的事情,保持设计的方法比临时拼凑更难。
    • 表现:编译时间长、源代码控制系统效率低。
  5. 不必要的复杂性:过度设计,包含当前无用的组成部分。
  6. 不必要的重复:滥用复制粘贴,忽视抽象。
  7. 晦涩性:模块难以理解,表达混乱。

2. 软件设计中的原则(对应原书第8、9、10、11、12、28章)

2.1 设计原则概览
序号 原则名称 缩写 英文全称 核心描述 对应设计模式
1 单一职责原则 SRP The Single Responsibility Principle 一个类(或接口)应只有一个发生变化的原因。 适配器模式(Adapter Pattern)、代理模式(Proxy Pattern)
2 开放-封闭原则 OCP The Open-Close Principle 软件实体(类、模块、函数等)应可扩展但不可修改。 策略模式(Strategy Pattern)、装饰者模式(Decorator Pattern)、观察者模式(Observer Pattern)
3 Liskov替换原则 LSP The Liskov Substitution Principle 子类型必须能够替换其基类型。 工厂模式(Factory Pattern)、模板方法模式(Template Method Pattern)
4 依赖倒置原则 DIP The Dependency-Inversion Principle 高层模块不应依赖低层模块,二者都应依赖抽象。 依赖注入(Dependency Injection)、服务定位器模式(Service Locator Pattern)
5 接口隔离原则 ISP The Interface Segregation Principle 为用户提供专用接口,避免强迫其依赖不需要的方法。 适配器模式(Adapter Pattern)、代理模式(Proxy Pattern)、装饰者模式(Decorator Pattern)
2.2 设计原则的价值与代价
序号 原则 违反的坏处 遵循的好处 代价
1 单一职责原则 代码复杂性增加、难以复用、高耦合性、测试困难 提高可维护性、增强可复用性、降低耦合性、简化测试 增加类的数量、初始设计复杂性、管理和组织难度、潜在的性能开销
2 开放-封闭原则 高风险修改、难以维护、影响其他功能 提高稳定性、增强灵活性、提高可维护性 设计复杂性增加、初始开发成本增加、可能的性能开销
3 Liskov替换原则 程序不稳定、难以维护、降低复用性 提高代码的灵活性和复用性、增强系统的稳定性、简化代码维护 设计复杂性增加、可能需要更多的抽象、初始开发成本增加
4 依赖倒置原则 高耦合、难以测试、降低灵活性 降低耦合度、提高可测试性、增强可扩展性 设计复杂性增加、初始开发成本增加、可能的性能开销
5 接口隔离原则 臃肿的接口、难以维护、降低灵活性 提高灵活性、增强可维护性、提高代码的可理解性 增加设计复杂性、初始开发成本增加、可能的代码冗余

个人理解:

  • 抽象带来自由:通过抽象隐藏实现细节,编写者和调用者都能获得更大的灵活性。
  • 抽象不足的代价:抽象不足会导致编写者和调用者都失去自由,代码难以维护和扩展。
  • 隐藏实现细节:将实现隐藏在接口后,编写者可以自由修改实现,调用者无需引入不必要的细节。
2.3 包和组件的设计原则
序号 分离 概述 原则名称 缩写 英文全称 描述
1 内聚性原则 帮助开发者决定如何将类划分到组件 重用-发布等价原则 REP Reuse-Release Equivalence Principle 重用的粒度就是发布的粒度
2 共同重用原则 CRP Common-Reuse Principle 一个组件中的所有类应共同重用
3 共同封闭原则 CCP Common-Closure Principle 组件中的所有类应对同一种变化共同封闭
4 组件耦合性原则 处理组件之间的关系,平衡可开发性和逻辑设计 无环依赖原则 ADP Acyclic-Dependencies Principle 组件之间的依赖关系不应形成循环
5 稳定依赖原则 SIP Stable-Dependencies Principle 依赖应朝向稳定的方向
6 稳定抽象原则 SAP Stable-Abstractions Principle 组件的抽象程度应与其稳定程度一致

3. 开发中的经验与教训

  • 避免重复犯错:将正确的代码封装为通用函数,避免重复错误。
  • 优先使用通用库:尽量使用通用库(如STL、Boost),避免重复造轮子。如果通用库中没有所需功能,可以自行开发通用库。

4. 总结

  • 抽象与接口的重要性:通过抽象和接口设计,可以显著提高代码的灵活性、可维护性和可复用性。
  • 设计原则的权衡:虽然遵循设计原则会增加初始设计的复杂性,但长远来看,能够显著提升代码质量和开发效率。
  • 识别与避免坏味道:通过识别和避免软件设计中的坏味道,可以有效提升代码的可读性和可维护性,降低后期维护成本。
posted @ 2025-02-20 06:46 荣-- 阅读(63) 评论(0) 推荐(0) 编辑
摘要: 目录概述PyTorch框架MNIST数据集讨论:什么是神经网络,它是怎样识别图片的训练过程分层输出层softmax归一化:让输出层的每个节点取值0~1之间,总和为1训练:缩小差值回顾:batch激活函数:非线性转换代码安装依赖库代码执行结果扩展: 在28*28的画布上手写数字进行识别:三轮训练的预测 阅读全文
posted @ 2025-02-18 22:57 荣-- 阅读(10) 评论(0) 推荐(0) 编辑
摘要: 目录概述OpenCV安装openvc素材案例1:图片的维度与通道代码补充案例2:图像的彩色通道概述代码执行结果案例3:图像的裁剪代码执行结果案例4:使用OpenCV的绘制功能代码执行结果案例5:均值滤波概述代码执行结果案例6:图像特征的提取代码执行结果案例7:模板匹配概述代码执行结果补充案例8:图像 阅读全文
posted @ 2025-02-17 23:53 荣-- 阅读(4) 评论(0) 推荐(0) 编辑
摘要: 目录《代码大全2》中的核对表《代码大全 2》《代码大全 2》的核对表需求架构前期准备主要的构建实践软件构造中的设计类的质量高质量的子程序防御式编程伪代码编程过程使用数据的一般事项变量命名基本数据类型使用不常见数据类型的注意事项组织直线型代码使用条件语句循环不常见的控制结构表驱动法控制结构相关事宜质量 阅读全文
posted @ 2025-02-16 16:02 荣-- 阅读(3) 评论(0) 推荐(0) 编辑
摘要: dab-adapter-cpp的类图: classDiagram class dispatcher { <<class>> } class dabBridge { jsonElement dispatch() } class dabMQTTInterface { -dabBridge bridge 阅读全文
posted @ 2025-02-05 21:43 荣-- 阅读(5) 评论(0) 推荐(0) 编辑
摘要: 目录概述DAB::dabclientdef宏def宏的展开nativeDispatch类类的模板参数构造函数参数最后两个模板参数的推导特化发生的时机std::string_viewstd::initializer_liststd::is_same_v 概述 dab-adapter-cpp 是一个 C 阅读全文
posted @ 2025-02-05 19:54 荣-- 阅读(14) 评论(0) 推荐(0) 编辑
摘要: CRTP(Curiously Recurring Template Pattern,奇异递归模板模式)是 C++ 中的一种设计模式。 基本概念 CRTP 是指一个类(通常是基类)以其派生类作为模板参数的模式。其基本形式如下: template <typename Derived> class Bas 阅读全文
posted @ 2025-02-05 19:14 荣-- 阅读(143) 评论(0) 推荐(0) 编辑
摘要: 说在前面的话 本文整理自不坑老师的视频公众号。 为什么要搭建本地环境 deepseek访问时,会出现系统繁忙 我们希望能搭建一个本地知识库,让AI格局自己的知识来进行创作 下载ollama ollama是什么 ollama的下载 官网下载: Download Ollama on Windows 特点 阅读全文
posted @ 2025-02-04 22:01 荣-- 阅读(1453) 评论(0) 推荐(0) 编辑
摘要: DAB C++ 版本设计模式应用实践 1. 命令模式 (Command Pattern) 设计目标 模块解耦:实现各模块独立编译、测试、运行,消除模块间直接依赖 扩展准备:为桥接模式实现奠定基础 依赖倒置:通过命令对象反转模块依赖方向 耦合降低:将模块间耦合简化为命令对象耦合 1.1 MQTT 模块 阅读全文
posted @ 2025-02-01 09:15 荣-- 阅读(145) 评论(0) 推荐(1) 编辑
摘要: 本文介绍了 DAB协议实现的开发过程。由于设备认证需要,团队面临了开发 DAB 软件的紧迫任务。 项目初期,团队深入学习了 DAB 协议,整理出 28 个核心接口,并提出了改进建议,成功推动了协议的优化。随后,团队设计了两套实现方案,最终选择复用设备内部的 MQTT 服务,尽管带来了安全风险,但通过云端授权和超时关闭机制有效缓解了问题。 在技术选型上,团队选择了 Node.js 以缩短开发周期并复用现有功能。尽管 Node.js 版本成功支撑了多个设备的认证,但仍存在部分设备不支持 Node.js 以及跨部门协调复杂的问题。为此,团队开发了第二版 DAB,采用 C++ 实现,解决了 Node.js 的局限性,并通过适配层实现了多平台支持。 开发过程中,团队通过单元测试、灵活的部署策略和适配层设计,显著提升了开发效率和质量。尽管项目取得了成功,但仍存在一些遗憾,如嵌入进程的部署方式增加了安全依赖,以及与实践结合的时机较晚。 最终,DAB 的开发不仅解决了技术难题,还优化了团队协作和项目管理流程,为未来的设备自动化测试奠定了坚实基础。 阅读全文
posted @ 2025-01-31 21:36 荣-- 阅读(387) 评论(0) 推荐(0) 编辑
点击右上角即可分享
微信分享提示