草庐IT

读C#代码整洁之道笔记04_重构C#代码识别代码坏味道

躺柒 2023-03-28 原文

1. 应用程序级别代码坏味道

1.1. 布尔盲点

  • 1.1.1. 由于函数使用布尔值而导致的信息缺失

  • 1.1.2. 解决方案是将布尔替换为枚举类型

1.2. 组合爆炸

  • 1.2.1. 不同的代码使用不同的参数组合来执行同一件事情的产物

  • 1.2.2. 解决方案使用泛型

1.3. 人为复杂性

  • 1.3.1. 简单的架构复杂化

  • 1.3.2. 解决方案务必保持软件的简单易懂(Keep It Simple,Stupid,KISS)

1.4. 数据泥团

  • 1.4.1. 相同的字段同时出现在不同的类和参数列表中时

  • 1.4.1.1. 说明系统中缺少类定义

  • 1.4.2. 识别并泛化缺失的类可以降低系统的复杂度

1.5. 粉饰注释

  • 1.5.1. 注释中用优美的词句掩盖代码的缺点

1.6. 重复代码

  • 1.6.1. 多次出现的代码

  • 1.6.1.1. bug=技术债务=程序员支出

  • 1.6.2. 解决方案将这些代码添加到当前项目的可重用类并放置在类库中

  • 1.6.3. 解决方案2:面向方面编程(AOP)是另一种删除样板代码的方法

1.7. 意图不明

  • 1.7.1. 他人无法轻易理解代码的意图

1.8. 可变的变量

  • 1.8.1. 不同操作之间多次更改的变量

  • 1.8.2. 消除变量的可变性,使其值更易于预测

  • 1.8.3. 函数编程

  • 1.8.3.1. LINQ

1.9. 怪异的解决方案

  • 1.9.1. 源代码中解决同样问题的方案多种多样

  • 1.9.1.1. 源代码中解决同样问题的方案多种多样

  • 1.9.1.2. 没有制定统一标准而造成

  • 1.9.1.3. 程序员并没有意识到系统中已经存在解决方案

  • 1.9.2. 解决方案:不同的重复的解决方案编写新类,并将最整洁最高效的方式添加到类中

  • 1.9.3. 解决方案2:适配器模式来统一不同的系统接口

1.10. 霰弹式修改

  • 1.10.1. 一种改动需要在多个类中进行修改

  • 1.10.1.1. 复杂的代码还会导致程序员认知负担过重

  • 1.10.2. 减少耦合可以使类更易于测试

  • 1.10.3. 将不属于类的代码移出到恰当的位置可以提高应用程序的可读性、可维护性与可扩展性

1.11. 解决方案蔓延

  • 1.11.1. 一种职责在不同的方法、类甚至库中均被实现

  • 1.11.2. 单一职责转移到同一个类中

1.12. 不可控的副作用

  • 1.12.1. 在产品中由于无法被质量保证过程发现而引起的问题

  • 1.12.2. 唯一的办法就是重构代码使其完全可测,并可以在调试期间查看变量的状态以确保程序的正确性。

2. 类级别代码坏味道

2.1. 过高的圈复杂度

  • 2.1.1. 大量的分支和循环

  • 2.1.2. 1~10

  • 2.1.2.1. 代码简单没有风险

  • 2.1.3. 11~20

  • 2.1.3.1. 较复杂,风险相对较低

  • 2.1.4. 21~50

  • 2.1.4.1. 引起注意,中等风险

  • 2.1.5. 超过50

  • 2.1.5.1. 风险高,必须重构

  • 2.1.6. 解决方案

  • 2.1.6.1. 使用工厂模式替换switch语句

  • 2.1.6.2. 改善if语句条件检测的可读性

  • 2.1.6.3. LINQ语句替换循环

2.2. 发散式变化

  • 2.2.1. 对代码进行一处更改,但是发现自己必须更改许多不相关的方法

  • 2.2.2. 原因

  • 2.2.2.1. 类结构不良造成

  • 2.2.2.2. 复制粘贴代码

  • 2.2.2.3. 利用基类和子类的关系实现继承

2.3. 向下类型转换

  • 2.3.1. 将基类转换为它的一个子类

2.4. 过度的字面量使用

  • 2.4.1. 将字面量保存在常量中

  • 2.4.2. 将字符串字面量放置在本地化资源文件中

2.5. 依恋情结

  • 2.5.1. 当一个方法花费大量的时间处理类中的代码而非自身的代码

2.6. 狎昵(xiá nì)关系

  • 2.6.1. 一个类若依赖另一个类的实现细节

  • 2.6.2. 类之间不应当相互依赖

  • 2.6.3. 类应当是自包含的

  • 2.6.4. 类之间应该尽可能少地互相了解彼此的底细

2.7. 不恰当的暴露

  • 2.7.1. 类暴露了其内部细节

  • 2.7.2. 打破了面向对象编程的封装原则

2.8. 巨大的类

  • 2.8.1. 务必令其尽可能小巧、整洁、易于阅读

2.9. 冗赘类

  • 2.9.1. 一种并不包含什么有效操作的类

  • 2.9.2. 和其他包含相似意图的类合并

  • 2.9.3. 削减继承层次结构

  • 2.9.3.1. 理想的继承层次是1

  • 2.9.4. 非常小的类还可以考虑采用内联的处理方法

2.10. 中间人类

  • 2.10.1. 仅将功能委托给其他对象

  • 2.10.2. 舍弃中间人直接和处理相应职责的类进行交互

  • 2.10.3. 将其与现有类合并

2.11. 孤立的变量和常量类

  • 2.11.1. 使用一个独立的类来定义系统不同部分使用的变量和常量

  • 2.11.2. 丢失其上下文而无法表达任何实际含义

  • 2.11.3. 移动到使用它们的位置

2.12. 基本类型偏执

  • 2.12.1. 使用常量作为字段名称

  • 2.12.2. 不恰当地使用常量保存信息

  • 2.12.3. 使用基本类型值而非使用对象

2.13. 被拒绝的遗赠

  • 2.13.1. 一个类继承自另一个类,却没有使用其所有方法

  • 2.13.2. 考虑是否真的需要基类

2.14. 夸夸其谈未来性

  • 2.14.1. 一个类的功能现在不需要,但是将来可能用到

  • 2.14.2. 死代码,应当将其删除

2.15. 命令,而非询问

  • 2.15.1. 将数据和操作数据的方法绑定在一起

  • 2.15.2. 一个对象包含逻辑,并要求其他包含数据的对象提供数据以供其执行操作,则应当将逻辑与数据合并到一个类中

2.16. 临时字段

  • 2.16.1. 不需要在对象的整个生命周期内存在的成员变量

  • 2.16.2. 将临时字段及操作这些字段的方法移动到它们自己的类中

3. 方法级别的代码坏味道

3.1. 不合群的方法

  • 3.1.1. 一个类中和其他方法截然不同的方法

  • 3.1.2. 考虑该方法的目的

  • 3.1.2.1. 确定哪里才是该方法最合适的落脚点了

3.2. 无用的代码

  • 3.2.1. 现存的方法无人使用

  • 3.2.2. 要识别无用的代码并将其删除

  • 3.2.3. 构造器、属性和变量也应遵循相同的原则

3.3. 过多的返回数据

  • 3.3.1. 远超客户端的调用

3.4. 过长或过短的标识符

  • 3.4.1. 标识符应当既能描述对象又简明扼要

3.5. 过长的代码行

  • 3.5.1. 应尽量将其格式化,在点号和逗号处换行

3.6. 过长的方法

  • 3.6.1. 方法应当只负责执行单一任务

3.7. 参数过多

  • 3.7.1. 方法参数数目超过3个

3.8. 过度耦合的消息链

  • 3.8.1. 当一个方法调用一个对象,继而调用另一个对象

  • 3.8.2. 消息链违反了迪米特法则

  • 3.8.2.1. 类只应当和离其最近的邻居通信

  • 3.8.2.2. 重构类,将所需的状态和行为放在距离其更近的位置

3.9. 过高的圈复杂度

3.10. 人为复杂性

3.11. 依恋情结

3.12. 狎昵关系

3.13. 冗赘方法

3.14. 中间人方法

3.15. 怪异的解决方案

3.16. 夸夸其谈未来性

3.17. 参见前文

有关读C#代码整洁之道笔记04_重构C#代码识别代码坏味道的更多相关文章

  1. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  2. ruby-on-rails - Rails 源代码 : initialize hash in a weird way? - 2

    在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has

  3. ruby-on-rails - 浏览 Ruby 源代码 - 2

    我的主要目标是能够完全理解我正在使用的库/gem。我尝试在Github上从头到尾阅读源代码,但这真的很难。我认为更有趣、更温和的踏脚石就是在使用时阅读每个库/gem方法的源代码。例如,我想知道RubyonRails中的redirect_to方法是如何工作的:如何查找redirect_to方法的源代码?我知道在pry中我可以执行类似show-methodmethod的操作,但我如何才能对Rails框架中的方法执行此操作?您对我如何更好地理解Gem及其API有什么建议吗?仅仅阅读源代码似乎真的很难,尤其是对于框架。谢谢! 最佳答案 Ru

  4. ruby - 模块嵌套代码风格偏好 - 2

    我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的

  5. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  6. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  7. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  8. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  9. 报告回顾丨模型进化狂飙,DetectGPT能否识别最新模型生成结果? - 2

    导读语言模型给我们的生产生活带来了极大便利,但同时不少人也利用他们从事作弊工作。如何规避这些难辨真伪的文字所产生的负面影响也成为一大难题。在3月9日智源Live第33期活动「DetectGPT:判断文本是否为机器生成的工具」中,主讲人Eric为我们讲解了DetectGPT工作背后的思路——一种基于概率曲率检测的用于检测模型生成文本的工具,它可以帮助我们更好地分辨文章的来源和可信度,对保护信息真实、防止欺诈等方面具有重要意义。本次报告主要围绕其功能,实现和效果等展开。(文末点击“阅读原文”,查看活动回放。)Ericmitchell斯坦福大学计算机系四年级博士生,由ChelseaFinn和Chri

  10. ruby-on-rails - 如何重构 "shared"方法? - 2

    我正在使用RubyonRails3.2.2,我想从我的模型/类中“提取”一些方法。也就是说,在不止一个类/模型中,我有一些方法(注意:方法与用户授权相关,并被命名为“CRUD方式”),这些方法实际上是相同的;所以我认为DRY方法是将这些方法放在“共享”模块或类似的东西中。实现该目标的常见且正确的方法是什么?例如,我应该将“共享”代码放在哪里(在哪些目录和文件中)?如何在我的类/模型中包含提到的方法?你有什么建议?注意:我正在寻找“RubyonRails制作东西的方式”。 最佳答案 一种流行的方法是使用ActiveSupport关注点

随机推荐