fupeisen

导航

统计

读书笔记《代码大全》2

1. 代码重复
 重复的代码几乎总是代表着对最初设计里彻底分解方面的一个失误。重复的代码同样违背了“

DRY原则”:不要重复自己“Don't Repeat Yourself.”。 还有一句更精辟的:“复制粘贴即设计之谬”。
2. 冗长的子程序
3. 循环过长或嵌套过深。
4. 内聚性太差的类。
 如果看到有某个类大包大揽了许多彼此无关的任务,那么这个类就该被拆分成多个类,每个

类负责一组具有内在的相互关联的任务。
5. 类的接口未能提供层次一致的抽象。
6. 拥有太多的参数的参数列表。
7. 类的内部修改往往被局限于某个部分。
8. 变化导致对多个类的相同修改
9. 对继承体系的同样修改
10. case语句需要做相同的修改
11. 同时使用的相关数据并未以类的方式进行组织。
 如果看到自己常常对同样一组数据进行操作,你也应当问问自己是否该将这些数据及其操作

组织到一个类里面。
12. 成员函数使用其他类的特征比使用自身类的特征还要多。
 这暗示着这一子程序应该被放到另一个类中,然后在原来的类里调用。
13. 过多使用基本数据类型
 示例:如果程序中使用了整形这种基本数据类型表示某种常见的实体,如货币,请考虑创建

一个简单的Money类,这样编译器就可以对Money变量执行类型检查,你也可以对赋给Money的值添加

安全检查功能。如果Money和Temperature都是整形,那么编译器就不会在你错误地使用

bankBalance = recordLowTemperature这样的赋值语句时提出警告。
14. 某个类无所事事
 有时重构会导致某个类无事可做。如果一个类看起来名不副实,那么问问自己能否将该类的

功能转交给其他的类,然后将这个类彻底去掉。
15. 一系列传递流浪数据的子程序。
 看看自己的代码,把数据传递给某个子程序,是否仅仅就为了让该子程序把数据转交给另一

个子程序。这样传来传去的数据被称为“流浪数据/tramp data”。 这样做也不是不行,如此传递特定数

据,是否与每个子程序接口所表示的抽象概念一致。如果这些子程序接口的抽象概念相同,那么他们之

间传递数据并无不妥。如果不是这样,那么就想些其他的办法让各个子程序的接口更加一致。
16. 中间人对象无事可做
17. 某个类同其他类关系过于亲密
18. 子程序命名不恰当
19. 数据成员被设置为公用。
 把数据成员设置为公用(public)绝对是一个糟糕的主意。这样会模糊接口和实现之间的界

限,其本身违背了封装的原则,限制了类在未来可以发挥的灵活性。
20. 某个派生类仅使用了基类的很少一部分成员函数
 这时,把派生类相对于基类的关系从“is-a”转变为“has-a”。即把基类转换成原来的派生类的

数据成员,然后仅仅为原来的派生类提供所需要的成员函数。
21.注释被用于解释难懂的代码
 注释在程序中扮演了重要的角色,但它不应当被用来为拙劣代码的存在而辩护。有箴言为证

:“不要为拙劣的代码编写文档——应当重写代码”(Kernighan and Plauger1978)
22. 使用了全局变量
23. 在子程序调用前使用了设置代码(setup code),或在调用后使用了收尾代码(takedown code

)。
这样的代码应当看作是一种警告:
C++示例:子程序调用前后的设置代码和收尾代码——糟糕的做法
WithdrawTransaction withdrawal;
withdrawal.SetCustomerId(customerId);
withdrawal.SetBalance(balance);
withdrawal.SetWithdrawalAmount(withdrawalAmount);
withdrawal.SetWithdrawalDate(withdrawalDate);

ProcessWithdrawal(withdrawal);

customerId = withdrawal.GetCustomerId();
balance = withdrawal.GetBalance();
withdrawalAmount = withdrawal.GetWithdrawalAmount();
withdrawalDate = withdrawal.GetWithdrawalDate();

另外一个类似的警告是你发现自己为WithdrawalTransaction创建了一个特殊的构造函数,完成一系列

简单的数据初始化。你的代码可能像下面这样:
C++示例:子程序调用前后的设置代码和收尾代码——糟糕的做法
withdrawal = new WithdrawalTransaction(customerId, balance, withdrawalAmount,

withdrawalDate);
withdrawal.ProcessWithdrawal();
delete withdrawal;

posted on   20214073-付沛森  阅读(9)  评论(0编辑  收藏  举报

编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示