代码大全 2 -- 读书笔记一

  1. 代码构建为什么重要
    1. 接口
    2. 继承
    3. 封装
    4. 创建类的原因
    5. 类的质量
  2. 子程序

代码构建为什么重要

构建活动的产物–源代码是对软件的唯一精确描述。
构建活动是唯一保证会完成的工作。

程序员是软件食物链中的最后一环。产品,设计师, 架构师一环套一环,哪一层做的不好,都会导致最下游的软件崩坏。

越上层引入的错误影响越大!

成为高级程序员的一个关键就是,当你开发程序任一部分的代码的时候,都能安全地忽视程序中尽可能多的其他部分。而类就是实现这一目标的首要工具。

类的基础是抽象数据类型(ADT)。它的目的是让你像在现实生活中一样操作实体,而不需要在低层实现上操作。

抽象的好处:

  • 让正确性显而易见,一个含有语义的子程序比枯燥的语句更容易让你验证是否正确

  • 程序更具有自我说明性,也就是很多地方提倡的子文档化

  • 无需在程序内部到处传输数据,数据被封在了实体中,获取都是实体的事情,外部不需要考虑

很多时候大家关注在底层的数据类型。但是我们其实应该尽可能地选择最高的抽象层次。如果堆栈代表的是一组员工,我们就应该把它看做是一些员工,而不是堆栈。我们也可以适当的分层,比如在堆栈这样的抽象层次之上再创建一个针对现实世界的问题的抽象层次。

类的接口应该提供一组明显相关的子程序。

类的内部可能包含很多的数据和子程序,可是类的使用者完全不需要了解。类的接口的抽象能力非常有价值。接口中的每个子程序都朝着这个一致的目标而工作。

如果类的接口不能展现出一种已知的抽象,他的内聚性就会很弱。我们就应该将他重新组织到几个职能更专一的类中。

我发现我们项目里面的 constant 文件的内聚性就很弱,大量的无关的常量被放进来了,应该重新组织。

每个类应该只实现一个 ADT,如果你发现一个类里面实现了不止一个或者你不确定实现了哪个,你就应该重新组织这部分。

接口

  • 我们要尽量提供成对的服务,注册就会有销毁

  • 把不相关的信息转移到其他类,如果某个类的一半子程序使用了一半的数据,另一半子程序使用了其他一半的数据,那就应该拆开了

  • 不要添加与接口抽象不一致的公共成员,一定要想想职责是不是分明

  • 尽可能让接口可编程,而不是表达语义!!

这一句的意思就是每个接口都有可编程的一部分,和表达语义的一部分。可编程的部分是能够在编译器的检测保证的。但是语义传出来的(比如必须先初始化才能调用)是人来保证的,就有可能会出错!尽可能让接口交代语义化的部分减少。

继承

怎么判断用不用继承?看职责,继承是一个“is a”的关系。EmployeeCensus 如果继承了 ListContainer,就意味着 EmployeeCensus 是一个 ListContainer,很明显不是。确认了职责之后要保证接口是符合这个职责的。

混乱的抽象层次会让程序越来越难理解。

派生类必须能够通过基类的接口而被使用,如果做不到,用组合吧。

频繁出现的 case 有时在按时继承可能是更好的选择。

封装

封装是一个比抽象更强的概念。抽象是可以让你忽略细节模型来管理复杂度,而封装是强制阻止你看到细节。

要采用最严格且可行的访问级别。

当我们读到那些暴露了其内部细节的代码时,要顶住诱惑,不要去寻找。

  • 不要对类的使用者做任何假设

  • 让阅读代码比编写代码更方便。代码要被阅读的次数远大于编写的次数,为了让代码编写更方便而降低代码的可读性是非常不经济的。不匹配的抽象得到的更方便的调用正是代码走下坡路的开始。合理比方便重要!!

调用代码要只依赖类的公开接口,而不是类的私有实现。

“Demeter”法则:A 对象可以调用自己的所有子程序,A 创建了 B,A 也可以调用 B 的所有子程序。B 创建的对象,A 不允许再调用。

只让对象之间单层依赖

创建类的原因

  • 为现实中对象建模

  • 为抽象对象建模,最好的例子是 shape,圆型和正方形都是 shape,shape 就是抽象

  • 降低程序复杂度

  • 隐藏实现细节

  • 限制改动区域

  • 隔离复杂度

  • 让参数传递更顺畅

目前 DI 代码里 DomainItem 传的参数太多,应该整理成传输对象

避免创建万能类

目前代码里 constant.js 有点万能类的感觉,知道的太多,反而无从查起

类的质量

  • 是否有一个中心

  • 接口能否让人清楚使用

  • 是否足够抽象,让人完全当一个黑盒子用

  • 开放的是否完整,人们是否需要动用内部数据

spreadjs 开发那里我动了内部的接口和数据来优化性能,理论上是他们的锅了

子程序

作者先举个不太好的例子,犯的错如下:

  • 子程序没有文档

  • 输入的变量的值变化了

  • 读取了全局变量,也就是不是纯函数了

  • 子程序没有单一并且明确的目的

  • 没有防范错误数据

子程序的设计内聚性是最重要的,每一个子程序只把一件事情做好。这样子程序的各个操作都是功能上的内聚了。

子程序的名字必须描述子程序所做的所有事情!

描述不了或者描述不好一定是需要换种方式重新组织

如果有地方你传递了大量参数,说明子程序之间的耦合太高,应该重新设计子程序,降低其间的耦合度。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 981909093@qq.com

文章标题:代码大全 2 -- 读书笔记一

文章字数:1.7k

本文作者:泽鹿

发布时间:2019-08-28, 16:45:23

最后更新:2019-08-28, 16:45:23

原始链接:http://panyifei.github.io/2019/08/28/读书笔记/代码大全2/1/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏