【Code Complete2】Note-1 [启发式编程、管理复杂度、隐藏设计]

【Code Complete2】_Note-1 [启发式编程、管理复杂度、隐藏设计]

文章目录

  • `【Code Complete2】`_Note-1 [启发式编程、管理复杂度、隐藏设计]
    • 启发式编程
    • 管理复杂度
    • 隐藏设计--减少“改动所影响的代码量”

启发式编程

​ **设计是一个启发的过程,充满了不确定性,具有探索性。**当一个编程问题摆在面前的时候,心里不免会有一种想法,“要不试试,这样说不定可以”。

​ **没有任何工具是放之四海皆准的。**虽然是写程序就像是在搬砖,这里补一块,那边补一块,但是砖似乎也是千奇百怪的。我们有时候在网上clone其他同行的开源代码,心里总是想着能不能在我这里直接编译成功,但是事情总是事与愿违,然后四处去找开源程序,结果不是让你交钱割韭菜,就是编不过的,最后在不懈的努力下,终于找到了可以编译的过的程序,这个课程设计作业也总算是完成了。相信大多数同学在上学的时候都经历过这个过程,这种事情做多了,我们便会想着去改开源程序,让他变成我们自己的东西,这个过程是充满挑战的,但是对我们也是帮助最大的,作为一个初学者,入门小白,我们不可能一开始就什么程序都自己写,搬砖式的学习,启发式的修改,似乎更值得我们去做。

​ **设计是自然而然形成的,通过我们不断的设计评估,非正式讨论,写实验代码,修改实验代码,不断地演化,完善。**写程序,第一件事是什么?毫无疑问是写个方案文档,我们一定要明确,没有任何一款程序方案文档是不经过几轮的迭代修改的,在写项目文档的时候,切记摒弃完美主义思想,你的第一版方案文档一定是有问题的,一定会在编码阶段,不断完善,不断修改的。



管理复杂度

软件的首要技术使命是管理复杂度

在这里插入图片描述

​ 保存子程序的短小精悍,在最抽象的层次工作上,减少人脑负担。复杂度小,易维护,松散耦合,搞扇入、低扇出;这是代码是否写的优秀的关键。

​ 如果说,我的既有程序写的不行,复杂度太高,怎么办?旧代码写的不行,可以在旧代码上写一层接口,来禁闭旧定义子系统之间的通信规则,把以前的“丑”,藏起来,以最大化减少复杂度,

无限制的子程序有限制的子程序
在这里插入图片描述在这里插入图片描述

程序中不应该有任何环形关系 a ==> b ==> c ==> a==>..



隐藏设计–减少“改动所影响的代码量”

​ 举个栗子,假设你有一个程序,其中的每个对象都是通过一个名为id的成员变量来保存-种唯一的ID。一种设计方法是用一个整数来表示ID,同时用一个名为g_maxId的全局变量来保存目前已分配的ID的最大值。每当创建新的对象时,你只要在该对象的构造函数里简单地使用id=++g_maxId这条语句,就肯定能获得一个唯一的ID值,这种做法会让对象在创建时执行的代码量最少。可这样设计可能有问题吗?

​ 很多多地方都可能会出错。

如果你想把某些范围的ID留做它用该怎么办? 如果你想使用非连续ID来提高安全性又该怎么办? 如果你想重新使用已销毁对象的ID呢? 如果你想增加一个断言来确保所分配的ID值不会超过预期的最大范围呢?

​ 如果程序中到处都是id=++g_maxId 这种语句的话,一旦上面说的任何一种情况出现,你就需要修改所有这些语句。另外,如果你的程序是多线程的话,这种方法也不是线程安全的(thread-safe)。

​ 创建新ID的方法就是一种你应该隐藏起来的设计决策。如果你在程序中到处使用++g_max1d的话,你就暴露了创建新ID的方法,也就是通过简单递增g_maxId。相反,如果你在程序中都使用语句id=NewId(),那就把创建新ID的方法隐藏起来了。你可以在NewId()子程序中仍然只用一行代码,return(++g_maxīd), 或者其他与之等价的方法。但如果日后你想把某些范围的ID留做它用,或者重用旧的1D时,只要对NewId()子程序的内部加以改动即可,无须改动几十个甚至成百个id=NewId()语句。无论 NewId()内部做了多么复杂的改动,这些改动都不会影响到程序的其他部分。

int NewId(){return (++g_maxīd)
}

​ 现在再假设你发现需要把 ID 的类型由整数改为字符串。如果你已经在程序内部大量地使用了int id 这样的变量声明的话,那么即使改用NewId()子程序也无济于事。你还得深入到程序内部,进行几十次甚至几百次的修改。

​ 因此,另一个需要隐藏的秘密就是ID的类型。对外界透露ID是个整型变量的做法,实质上是在鼓励程序员们对ID使用针对整数的操作,如>、<、=等等在C++里,你可以简单地使用typedef来把ID定义为 IdType–一个可以解释为int 的用户自定义类型–而避免将其直接定义成int 类型。在 C++和其他语言中,你也可以创建一个简单的 IdType类。再强调一下,隐藏设计决策对于减少“改动所影响的代码量”而言是至关重要的

int NewId(){return (++g_maxīd)
}

​ 信息隐藏在设计的所有层次上都有很大作用–从用具名常量替代字面量,到创建数据类型,再到类的设计、子程序的设计以及子系统的设计等


那么,我要隐藏些什么?

  • 易改变的区域;
  • 对硬件依赖的区域;
  • 困难的设计区域;
  • 状态变量;

对于状态变量,使用枚举类型比较好;我们一开始可能会使用布尔变量**来定义出错状态,然后又发现用具有ErrorType_None、ErrorType_WarningErrorType_Fatal等值的枚举类型来表示该状态更好。

布尔变量:是一种数据类型,它只能有两个可能的值:真(true)和假(false)。



感谢阅读,欢迎大家一起交流讨论。

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

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

相关文章

记录|cmd方式恢复U盘中的数据

目录 前言一、CMD恢复Step1.Step2. 更新时间 前言 参考文章&#xff1a; u盘数据误删怎么恢复&#xff1f;安利8款数据恢复软件免费版&#xff08;2024 NEW&#xff09; 回家后&#xff0c;家人说U盘里的歌突然没有了。我就用电脑看了看&#xff0c;发现电脑中能看到U盘中是满的…

修改启动方案

AMP设置为1Linux&#xff08;CPU0&#xff09; 3HAL&#xff08;CPU1、 2、 3&#xff09; 配置。 用vscode打开its 配置文件rk3568_amp_linux.its文件修改 /* SPDX-License-Identifier: BSD-3-Clause */ /** Copyright (c) 2022 Rockchip Electronics Co., Ltd.*//dts-v1/; /…

【优秀python算法毕设】基于python时间序列模型分析气温变化趋势的设计与实现

1 绪论 1.1 研究背景与意义 在气候变化日益受到全球关注的背景下&#xff0c;天气气温的变化已经对人们的生活各方面都产生了影响&#xff0c;人们在外出时大多都会在手机上看看天气如何&#xff0c;根据天气的变化来决定衣物的穿着和出行的安排。[1]如今手机能提供的信息已经…

【大模型】基于LoRA微调Gemma大模型(1)

文章目录 一、LoRA工作原理1.1 基本原理1.2 实现步骤 二、LoRA 实现2.1 PEFT库&#xff1a;高效参数微调LoraConfig类&#xff1a;配置参数 2.2 TRL库SFTTrainer 类 三、代码实现3.1 核心代码3.2 完整代码 参考资料 大模型微调技术有很多&#xff0c;如P-Tuning、LoRA 等&#…

操作系统杂项(八)

目录 一、简述互斥锁的机制&#xff0c;互斥锁与读写的区别 1、互斥锁机制 2、互斥锁和读写锁 二、简述信号量及其作用 1、概念 2、原理 3、作用 三、简述进程、线程的中断切换过程 1、进程上下文切换 2、线程上下文切换 四、简述自旋锁和互斥锁的使用场景 1、互斥…

宝塔单ip,新建多站点

报错如上&#xff1a; 那么如何新建多站点呢 先随便写个名字上去&#xff0c;然后再重新绑定别的端口… 这个时候访问99端口即可 。 如果是有域名&#xff0c;则不需要这样做 、直接80端口也可以多站点

数据缺失补全方法综述

数据缺失补全方法综述 摘要1. 引言2. 数据缺失的类型3. 数据缺失补全方法3.1 简单插补方法3.1.1 均值插补3.1.2 中位数插补3.1.3 众数插补3.1.4 前向填充和后向填充3.1.5 线性插值3.1.6 多重插补 3.2 基于模型的插补方法3.2.1 线性回归插补3.2.2 加权回归插补3.2.3 主成分分析&…

STM32智能工业监控系统教程

目录 引言环境准备智能工业监控系统基础代码实现&#xff1a;实现智能工业监控系统 4.1 数据采集模块 4.2 数据处理与控制模块 4.3 通信与网络系统实现 4.4 用户界面与数据可视化应用场景&#xff1a;工业监控与优化问题解决方案与优化收尾与总结 1. 引言 智能工业监控系统通…

Navicat premium最新【16/17 版本】安装下载教程,图文步骤详解(超简单,一步到位,免费下载领取)

文章目录 软件介绍软件下载安装步骤激活步骤 软件介绍 Navicat是一款快速、可靠且功能全面的数据库管理工具&#xff0c;专为简化数据库的管理及降低系统管理成本而设计。以下是对Navicat的详细介绍&#xff1a; 一、产品概述 开发目的&#xff1a;Navicat旨在通过其直观和设计…

HTML前端面试题之<iframe>标签

面试题&#xff1a;iframe 标签的作用是什么?有哪些优缺点 ? 讲真&#xff0c;刷这道面试题之前我根本没有接触过iframe&#xff0c;网课没讲过&#xff0c;项目实战没用过&#xff0c;但却在面试题里出现了&#xff01;好吧&#xff0c;我只能说&#xff1a;前端路漫漫&…

构建基于Spring Boot的SaaS应用

引言 在设计和实现SaaS系统时&#xff0c;安全性是至关重要的考虑因素。一个全面的安全策略不仅能保护系统免受恶意攻击&#xff0c;还能确保用户数据的机密性、完整性和可用性。本文将探讨在SaaS架构中实现数据加密、敏感信息保护以及应用安全的最佳实践和技术方案&#xff0…

如何恢复最近删除的文件?5种简单方法!

数据丢失在我们的工作生活中经常发生。当你决定清理硬盘或U盘时&#xff0c;你会删除一些文件夹或文件。如果你通过右键单击删除文件&#xff0c;则可以很容易从回收站恢复已删除的文件。但是&#xff0c;如果你按Shift Delete键、清空回收站或删除大于8998MB的大文件夹&#…

C++ | Leetcode C++题解之第278题第一个错误的版本

题目&#xff1a; 题解&#xff1a; class Solution { public:int firstBadVersion(int n) {int left 1, right n;while (left < right) { // 循环直至区间左右端点相同int mid left (right - left) / 2; // 防止计算时溢出if (isBadVersion(mid)) {right mid; // 答案…

element 结合 {} 实现自适应布局

通过el-row el-col 实现 例如 :xl“{ 1: 24, 2: 12, 3: 8, 4: 6 }[tableData.length] || 6” length 1 2 3 4 、代码数量为 1 2 3 4 >4 时不同卡片数量时尺寸的配置

MySQL4.索引及视图

1.建库 create database mydb15_indexstu; use mydb15_indexstu;2.建表 2.1 student表学&#xff08;sno&#xff09;号为主键&#xff0c;姓名&#xff08;sname&#xff09;不能重名&#xff0c;性别&#xff08;ssex&#xff09;仅能输入男或女&#xff0c;默认所在系别&a…

linux下usb抓包:wireshark+usbmon

step1. 加载usbmon模块 sudo mount -t debugfs none /sys/kernel/debug #这一步一般不用做&#xff0c;debugfs默认都是挂载的 sudo modprobe usbmon #如果这个命令找不到usbmon&#xff0c;那手动从/lib/modules中insmod sudo apt-get install wireshark 若加载成功&…

告别繁琐地推!Xinstall如何一键优化你的App地推方案

在这个移动应用遍地开花的时代&#xff0c;App地推活动早已成为各大厂商获取新用户、提升品牌曝光度的重要手段。然而&#xff0c;传统地推方案中的种种弊端&#xff0c;如填写地推码/邀请码的繁琐、渠道打包的工作量繁重、人工登记上报的不准确等&#xff0c;无一不在拖慢地推…

纯电SUV又一个卷王,比亚迪都没它狠

文 | AUTO芯球 作者 | 雷慢 太狠了&#xff0c;就在刚刚&#xff0c; 我劝阻了一个高中同学暂时不要买宋PLUS纯电版&#xff0c; 因为又一个新能源卷王出现了&#xff0c; 在卷价格上&#xff0c;宋PLUS都没它狠。 不信你们看&#xff0c;埃安V第二代刚发布&#xff0c; …

如何快速抓取小红书帖子评论?两大实战Python技巧揭秘

摘要&#xff1a; 本文将深入探讨两种高效的Python方法&#xff0c;助您迅速获取小红书文章下方的所有评论&#xff0c;提升市场分析与用户洞察力。通过实战示例与详细解析&#xff0c;让您轻松掌握数据抓取技巧&#xff0c;为您的内容营销策略提供有力支持。 如何快速抓取小…

可见性::

目录 定义&#xff1a; 解决方法&#xff1a; ①使用synchronized实现缓存和内存的同步 修改一&#xff1a; 加入语句&#xff1a; 代码&#xff1a; 修改2&#xff1a; 在代码块中加入&#xff1a; 代码&#xff1a; 执行结果&#xff1a; 原因&#xff1a; ②使用…