• Clean Code


    • 为什么看这本书?

    如这本书的名字意思,写出整洁的代码。整洁的代码,对以后的自己维护之前写的代码更加方便。代码混乱会导致难以维护,bug越修越多。
    个人认为整洁的代码,就是别人没有改进的余地。
    具体来说就是:

    1. 能够通过所有的测试
    2. 没有重复代码
    3. 体现系统中的全部设计理念
    4. 包括尽量少的实体,比如类、方法、函数等
    • 整洁代码
    • 有意义的命名
    1. 名副其实(有意义的命名,比如魔术数字)
    2. 避免误导(相似长名变量)
    3. 区分有意义的命名(意思相近的名称,比如Manager,Dirver)
    4. 类名(名称作为类名)
    5. 方法名(动词作为类名)
    • 函数
    1. 短小
    2. 只做一件事(一个函数只做一件事,如果它做了二件事,把它拆分成二个函数)
    3. 每个函数一个抽象层次(你的代码混乱,极大可能是你并没有很好的面向对象(抽象这个对象),函数的层次划分)
    4. 使用描述性的名称
    5. 函数参数,参数个数越少越好(0>1>2,超过3个你需要考虑下)
    6. 无副作用
    7. 分割指令和询问
    8. 使用异常返回错误代码(?)
    9. DRY (消除重复代码)
    10. 结构化编程 一个入口一个出口    做法:分解函数、修改名称、重复消除。保持测试通过
    • 注释

    理想情况,你的代码自我注释(即命名好,一看就知道表达的意思和功能,不需要额外的注释)

    • 格式

    代码格式关乎沟通。只要团队统一格式既可以了。

    • 对象和数据结构

    避免数据结构和对象的混用
    对象暴露行为,隐藏数据
    面向对象,添加一个新对象方便,但是添加函数麻烦
    面向过程

    • 错误处理

    使用异常而不是返回码(使用错误代码,会有比较多的if else判断,没有使用异常清楚)
    如果异常打断正常业务逻辑,可以使用特例模式
    不要返回null值
    传递null值,返回异常或者特例模式

    类应该短小
    单一职责原则(一个类只有一个需要修改的理由)
    内聚()
    隔离修改(使用抽象类,依赖倒置原则,依赖于抽象,不依赖于细节)

    • 系统

    将系统的构造和使用分开()
    依赖注入或控制反转(构造和使用分离)

    • 启发与味道
    • 注释

    不恰当的注释。注释只应该与代码又换,设计的技术信息。不该有作者,修改日期
    废弃的注释(发现就删除掉)
    冗余注释(只描述的东西)
    糟糕的注释(注释要好好写,别画蛇添足,保持简洁,语法和拼写正确)
    注释掉的代码

    • 环境

    需要多少步才能实现的构建
    需要多少步才能做到的测试

    • 函数

    过多的参数(0>1>2>3,3个以上要避免)
    输出参数(违反直觉,处理:修改对象的状态)
    表示参数(输入参数有bool值)
    死函数(没有人调用的函数需要删除)

    • 一般性问题
    1. 一个源文件存在多种语言
    2. 明显的行为未被实现(不考虑大小写等)
    3. 不正确的边界行为(证明边界的情况, 别依赖直觉,编写测试)
    4. 忽视安全(关闭编译器警告,关闭失败测试,过后处理)
    5. 重复(重复(遗漏了抽象),不同模块的相同switch语句,使用多态来解决, 模板方法和策略模式消除算法重复)
    6. 在错误的抽象层级上的代码
    7. 基类依赖于派生类(基类对派生类一无所知)
    8. 信息过多(提供的结构,函数扫,变量少)
    9. 死代码(不执行的代码,删除)
    10. 垂直分隔(变量和函数应该在靠近被使用的地方定义)
    11. 前后不一致(一致性)
    12. 混淆视听(没有用到的变量,不调用的函数,没有信息量的注释移除)
    13. 人为耦合(不相互依赖的东西不该耦合,根源是将变量、常量、函数不恰当放在临时方便的位置)
    14. 特性依恋(视情况而定)
    15. 旋转算子参数(函数传入bool值, 有选择操作的参数,int,Enum等,使用多个函数,通常要由于向单个函数传递某些代码来选择函数行为)
    16. 晦涩的意图(联排表达式。匈牙利语标记法。魔术数字)
    17. 位置错误的权责(PI放在Math?Trigonometry?Circle,最小惊异原则,代码应该放在读者自然而期待它所在的地方,换位置思考)
    18. 不恰当的静态方法(需要多态,静态函数使用确保没有机会打算让他有多态行为)
    19. 使用解释性变量
    20. 函数名称表达行为(day.add(5), 添加5天?5星期?5小时?,如果需要看文档知道要做什么,请修改更好的函数名称)
    21. 理解算法
    22. 把逻辑依赖改为物理依赖(依赖者模块不应该对被依赖者模块有假定,应当明确查询后者的全部信息)
    23. 使用多态替代IF else / switch case
    24. 遵循标准约定
    25. 用命名常量代替魔术数字
    26. 准确(明确自己为何要这么做)
    27. 结构胜于约定(多态vs switch)
    28. 封装条件
    29. 避免否定性条件(if (!express))
    30. 函数只该做一件事
    31. 遮蔽时序耦合(使用创建序列暴露给时序耦合,每个函数产生下个函数的结果)
    32. 封装边界条件
    33. 函数应该只在一个抽象层级上
    34. 在较高层级放置可配置数据(较低层级并不拥有这些常量值)
    35. 避免传递浏览(火车失事, 协作者提供全部服务)
    • java

    通过使用通配符避免过长的导入清单(包导入
    不要继承常量
    常量 vs 枚举(不用担心越界)

    • 名称

    采用描述性名称(取名不要太快)
    名称和抽象层级相符(不要取沟通实现的名称,取反映类或函数抽象层级的名称model(dial, disconnect) )
    尽可能使用标准命名法(装饰者模式, decorator)
    无歧义的名称
    较大作用范围选用较长名称(较小范围可以很短名称)
    名称应该说明副作用(getOos ,如果不存在,创建一个, =》createOrReturnOos)

    • 测试

    测试不足(测到所有可能失败的东西)
    使用测试覆盖率
    别略过小测试(小测试易与编写,文档价值高于编写成本
    被忽略的测试就是对不确定事物的疑问(需求不明确)
    测试边界条件
    全面测试相近的缺陷(某个函数有一个缺陷,那个函数可能还有另外的缺陷)
    测试失败的模式有启发性(看到测试失败,啊哈)
    测试覆盖率的模式有启发性
    测试应该快速

    • 总结

    上面的那一系列清单大致很难说是完备的了,但是你遵循这些原则不应该是目标,清单是列不完的,它背后的那一套价值体系才是自己需要学习的,自己需要自我驱动
    ————————————————
    版权声明:本文为CSDN博主「y z x」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/a352614834/article/details/89420266

  • 相关阅读:
    9个开源支付项目,用来学习如何实现支付功能
    documentdb
    Azure Redis
    Azure Diagnostics
    Content Delivery Network (CDN)
    MVVM design pattern
    Azure Cloud Application Design and Implementation Guidance performance-optimization
    Azure Nosql
    设计原则与模式
    C# Yield
  • 原文地址:https://www.cnblogs.com/hanfanfan/p/16253541.html
Copyright © 2020-2023  润新知