Ws.
文章
关于
返回
代码整洁之道阅读思考
2023-01-15
编程
规范

一、整洁代码的定义

  • 整洁的代码只做一件事情
  • 逻辑不清楚,性能不好的代码,会让别人非常想改它,然后改的更乱了。

二、命名

  1. 不能提供更多额外信息的词汇不要用。 比如一个 Product 类,还有一个 ProductInfo 和 ProductData,其中 Info 和 data 并不能提供更多的信息。Info和 data 就像是 a\an\the 这种词都是冗余。

  2. 避免误导,就是程序名和变量名要名符其实。比如 OrderList 就应该是一个 list,而不应该是一个对象。函数的名称要和函数所做的动作一致。假如发现无法有很好的函数名称形容这个函数,那说明这个函数做的事情太多了,需要进行拆分。

  3. 名称宁愿长点,也不要缩写成别人无法理解的单词。

  4. 不要前缀! 因为代码读的越多,眼中就慢慢会自动忽略前缀。

  5. 类名和对象名应该是名词或者名词短语。例如:Customer、WikiPage、AddressParser。类名不应该是动词。避免:Manager,Processor 这种类名,因为他是比较笼统的概念。

  6. 方法名应该是动词或者动词短语。如 PostPayment, Delete 。初始化一个类时

    Complex fulcrumPoint = new Complex(20, 30)
        
    //这种方式会更好
        
    Complex fulcrumPoint = Complex.FromRealNumber(20,30)
    

    可以考虑将对应的构造器设为 priate,强制使用各种方式

  7. 每个概念对应一个单词。给每个抽象出来的对象或者操作规定一个名称。比如fetch、retrieve、get他们都是获取的意思时,要给出对应的场景单词。注意区分insert、append并替代add使用。尽可能使用email代替emailAddress,因为后者几乎没有提供比前者更多的信息。

  8. 对于词义比较广泛的,需要进行限制,比如 get、add、manage 等。

    • get 是获取对象属性
    • fetch 从远程获取数据
    • load 从文件或者存储中获取数据
    • query 从数据库里获取数据
    • calculate 计算出来的数值
    • find 从数组中查找数据
    • createparsebuild 从数据生成数据

    常用单词:

    add/remove        increment/decrement       open/close
    begin/end            insert/delete                      show/hide
    create/destory    lock/unlock                        source/target
    first/last              min/max                             start/stop
    get/put                next/previous                     up/down     
    get/set                old/new
        
    新增: add, new, create, make, build, generate
    更新: update, set, transform, 
    获得:get, load, fetch, calculate, find, search, filter, query
    删除:remove, delete, clear, 
    接口:Ajax
    
  9. 很少有名称是可以自我说明的,比如 name, 所以需要有上下文环境,上下文环境可以是名称前缀,当然抽象成类更好。

三、函数

  1. 函数的第一规则是短小,第二规则还是短小!
  2. 函数只做一件事情。做好这件事情,只做这一件事情
  3. 函数的抽象层级要统一,就是函数内操作的颗粒度要统一。比如一个函数要渲染页面, render(View) 是高层次抽象,然后 printString(String) 这里就是底层的实现,他们应该要进行分层。就像我们设置里面,先进入控制面板,然后找到所属的模块,然后细节的操作。
  4. 函数参数,最理想的参数数量是0,应该避免三个参数以上的函数,有足够特殊的里有才能用三个以上的参数。参数太多可以用责任链设计模式。
  5. 禁止标识参数,就是 Flag 或者 Switch,不准像函数传入布尔值。这标明了函数没有做一件事情,假如为 true 会这么做,假如为 false 会这么做。
  6. 如果函数参数看来需要两个或者三个以上,那说明其中一些参数应该被封装成类了。
  7. 函数要么做什么事,要么回答一些事。但二者不可兼得。把动作查询分开。当然有时候动作的结果就是我们查询的对象,这时候直接返回。但是不要既做动作,又对结果进行额外的查询。
  8. try...catch...中的代码块,应该抽离成函数
  9. 不要重复!重复是复杂度的根源之一。很多原则和实践规则都是为了避免重复

四、注释

  1. 注释不能美化糟糕的代码!
  2. 注释只应该出现在理解困难或者容易出错的地方,能不用就不要用。
  3. 不准保留注释掉的代码,统统删干净

五、格式

  1. 统一的缩进格式
  2. 代码行应该尽可能短小,最好不要超过120字
  3. 代码格式要团队进行统一,使用编辑器工具进行限制
  4. 类的组织,首先应该是常量, 然后是属性,然后是公共函数,对应的私有函数要放在调用者附近。公共函数应该在变量之后

六、对象和数据结构

  1. 类并不是用取值和赋值将私有变量对外使用。二是要暴露抽象接口,让用户无需了解数据结构就可以使用。
  2. 对象把数据隐藏于抽象之后,暴露操作数据的函数。 数据结构暴露起数据结构,没有提供有意义的函数。
  3. 过程式代码(使用数据结构的代码),难以修改数据结构,因为会影响函数,但是容易修改函数。
  4. 对象式代码,难以添加新函数,因为会影响很多类。
  5. 模块不应该了解对象内部的数据结构,对象不应该通过存取器暴露内部结构。
  6. 数据对象,只有公共变量,没有函数的类。被称为数据传送对象。作用就是将原始数据转化为类的操作,比如 ActiveRecord

七、错误处理

  1. 使用异常而不是返回码。 意思是主函数调用子函数时,子函数不应该返回 true 或者 false 等返回码,这样主函数还需要进行判断,而应该直接抛异常。由统一的错误处理进行处理。
  2. 不要返回 null 值!不要传递 null 值

八、范围

  1. 一个类要有其对应的范围。不能啥都干。比如 StoreHandler 只应该做返回值是Store 的操作,获取 Store 的 Price 应该放到 PriceHandler
  2. 使用接口类限制边界

九、类

  1. 类的单一权责。系统应该由很多短小的类而不是少量巨大的类构成。
  2. Controller 过于臃肿,而且 controller 里面的方法不便于其他 controller 进行调用。所以将 controller 逻辑提取出来,根据函数所获得的结果进行汇总,然后控制逻辑层,防止逻辑层大爆炸。为了防止逻辑层大爆炸,就要求逻辑层有比较想尽的文档,在编写之前可以先查阅文档是否已经存在有类似的函数。对与逻辑层的起名不要包含业务层信息。仅描述对资源的获取,包含三个部分,请求的资源,请求的条件,请求返回的格式。
Ws.
Keep looking don't settle
@2024 Wenson | Code the Ambition | V1.1.2