代码是我们用来表达需求的语言,而对于我们而言,代码将会是我们之后无法避免而且需要学好的一项技能,而对于基本的编写代码的整洁将会是提高我们之后编写和阅读修改的效率的一个很好的方法,其实对于我这个接触代码不多的初学者而言,编写代码一开始会有着许许多多的不规范的地方,对于基本的格式、命名等等有一定的针对性的要求的话,对于之后的编写和基本的习惯的养成会有很大的帮助。
编写的不规范常常源于不耐烦,或者说将就,“算了吧,能跑就行!”有时候这样的念头往往是糟糕的代码的开始,laterequalnever,还是需要养成一个好的习惯。混乱往往会制造混乱,降低效率。而相反,整洁的代码往往会减少人们修改的时间,会提高效率。相对地,代码的编写的时候需要注意一些细节,整洁的代码力求集中,每个函数、每个类和每个模块都全神贯注于一件事,完全不受四周细节的干扰和污染。另外还会有许多具体的要求,那么接下来我们将分为一些小的部分具体讲解。
命名在代码编写过程中是无法避免的,函数、变量等等都需要命名,一个好的命名能够让我们清楚地明白一个对象的功能等等。对于命名而言,最重要的就是名副其实,也就是说,我们需要关注的问题不在于代码的简洁度,而是在于代码的模糊度,在于代码对应的功能是否准确。在实际的命名过程中,我们也需要注意一些问题,首先我们需要避免误导,对于一些十分相似或者具有专门用途的名称尽量不要使用。另外,对于一个类别的命名,需要做到有意义的区分,而不是一些意义含混的废话。简单来说,要区分名称,就要以读者能鉴别不同之处的方式来区分。除此之外,我们还需要注意命名应该使用可以读的出来、可以收索的名字,避免使用编码和产生思维映射以及一些双关语和太过于专业的词语。言到意到,意到言到,这才是最完美的状态。最后,我们在命名的时候需要添加有意义的语境和避免添加一些无用的语境,常常我们在命名的时候会一串词一起命名,这个时候往往会忽视语境,由于有些词连在一起我们很容易想起它的意义,但是单独拎出来的时候往往会造成阅读的困难,于是我们需要添加一些必要的语境。
函数在我们的代码编写中有着极其重要的作用,函数的规则是要短小,另外,每个函数都应该一目了然,只说一件事。而且,每个函数都依序把你带到下一个函数。这样的函数能够让你很快的了解其对应的功能,而且具有很强的关联性,能够使得我们了解接下来的步骤。用文中的话来说,就是函数应该做一件事,做好这件事,只做这一件事。对于具体的函数的编写,也需要有一定的规范,首先,使用描述性的名称,对于一类别的函数,命名方式要保持一致,使用一脉相承的短语、名词和动词。关于函数参数,最理想的状态是没有参数,其次是一个参数、两个参数,尽量不要使用三个及以上的参数,参数的命名同样需要做到名副其实。由于函数应该做一件事,要么做什么事,要么回答什么事,所以我们需要将指令和询问分隔开来,另一方面,我们需要使用异常替代返回错误码,这样错误处理代码就能从主路径代码中分离出来。还有很重要的一点,千万不要重复。
注释仿佛成为我们阅读代码的一样神器,但是依靠注释的我们从一开始就是错误的,真正好的代码是不需要注释的。当然,适当的注释在一些场合也是需要的。但是注释只是一个缓解的作用,无法美化糟糕的代码。好的注释包括法律信息版权、提供信息、意图的注释、警示等等,坏的注释往往会提供多余、误导的信息,或者信息过多,联系不紧密导致我们阅读的过程中花费过多的时间在注释上,而完全忽略了代码本身,还有就是我们经常做的一个行为,注释掉代码,我们往往为了图方便,常常会注释掉代码,但是其实有一些我们以及更新了一个版本,但是旧的代码依旧存留着,没有删除,这样反而照成了一定的阻碍。
代码格式很重要,需要我们严肃对待。主要分为两种,一是垂直格式、二是横向格式。关于垂直格式,我们主要需要关注的是区隔、距离和顺序,具体来讲,我们需要注意我们编写代码的顺序和每个区域的间隔和距离,这对于我而言还是比较使用的,由于VHDL是并行的语句,所以在编写的过程的顺序和距离对于我们阅读代码会具有很大的帮助,读后感www.simayi.net如果按照一定的流程顺序写下来,我们便能够按照流程了解各个部分的功能和实际的输入输出和具体的实际信号的连接。至于横向格式,我么需要注意水平对齐、缩进和空范围,这对于我们编写过程中每个层次会看的很清楚。另外,如果处于一个团队中,需要制定一个团队规则,这样大家编写的代码更加容易互相阅读和互通。
关于对象和数据结构,两者都有优缺点,根据我们具体的使用来变化。对象曝露行为,隐藏数据,便于添加新对象类型而无需修改既有行为,同时也难以在既有对象中添加新行为。数据结构曝露数据,没有明显的行为。便于向既有数据结构添加新行为,同时也难以向既有函数添加新数据结构。两者之间存在着反对称性,并没有优劣之分,只是根据使用场合灵活转变就可。
一个完整的程序考虑全部情况的话,往往需要考虑错误处理,错误处理是在程序的基础上的,但是不能够更改原来程序的逻辑。最好的情况是我们在具体的逻辑设计的过程中就将错误处理考虑在内,只需要我们去根据具体的错误的语境返回对应的异常值,这样我们就能够根据返回的异常值判断错误的情况。另外,我们需要使用不可控异常,并且不能返回返回码和返回、传播NULL值,这样会导致情况复杂化,反而添加了不必要的部分,增加了代码的阅读难度,降低了可读性。
我们常常需要使用第三方的程序或者和别人对接程序,这样的情况下边界就显得尤为重要。在接口提供者和使用者之间,存在与生倶来的张力。第三方程序包和框架提供者追求普适性,这样就能在多个环境中工作,吸引广泛的用户。而使用者则想要集中满足特定需求的接口。这种张力会导致系统边界上出现问题。这也就要求我们浏览和学习边界,且使用学习性测试来确保第三方程序包按照我们想要的方式工作。但是有时候我们也会遇到接口还没有定义的情况,这个时候我们可以采用尚不存在的代码,假想一个接口,从距离接口最远的部分开始编写。另外,由于接口往往可能会更改,这也就导致我们的程序需要为之更改,这也就要求我们的边界整洁,尽量少的依靠边界的值,而尽量多的依靠你能控制的东西,免得日后受它控制。
单元测试往往会伴随着对应的部分代码出现,他们使用频率和代码差不多。因此,我们在编写单元测试的过程中,也需要要求代码整洁,相对地,如果测试代码不整洁,我们为了测试一个代码段的功能,需要花费很多的时间去更改测试代码。整洁的代码要求可读性,而且只测试一个概念,具有一个断言语句。测试的整洁需要遵循一些规则:快速、独立、可重复、自足验证(测试应该有布尔值输出)、及时。
系统是一个程序的大的框架,由许许多多的部分组成。在具体的系统的构造和使用,我们需要将这两个部分分开。具体的做法之一是将全部构造过程搬迁到main或被称之为main的模块中,在设计其他部分的,我们需要假设所有对象都已经正确构造和设置,在这个基础上使用。另外一种可以实现分离构造与使用的方法是依赖注入,其中控制反转是一种应用手段,它将第二权责从对象中拿出来,转移到另一个专注于此的对象中,从而遵循了单一权责原则。在依赖管理情景中,对象不应负责实体化对自身的依赖。反之,它应当将这份权责移交给其他“有权力”的机制,从而实现控制的反转。因为初始设置是一种全局问题,这种授权机制通常要么是main例程,要么是有特定目的的容器。另外,我们在设计系统的时候,根据现有的容量进行设计,在到达一定使用率的时候,我们再考虑扩容的问题,而不是一开始就将容量设置为一个很大的值,那样反而会浪费资源。另外,我们可以使用一定的标准,这样的话,对于重复使用的想法能够提高一定的效率。
简单设计具有四条规则:运行所有测试、不可重复、达了程序员的意图、可能减少类和方法的数量。运行所有测试是这一切的前提,只有通过了测试的系统,才能朝着整洁的方向发展,在通过了测试的基础之上,我们再利用后面三条规则进行重构,并重新考虑设计退步了吗,一步一步向下发展。另外,我们也需要做到最基本的不可重复、清晰表达作者意图和函数数量少的条件。
并发编程具有很多的好处,但是同时也具有一定的难度。并发能够解耦,能够改进应用程序的吞吐量和结构。但是,并不是说,并发编程就一定能够优化程序。它也会带来一定的开销和改变,在合适的场合和正确的使用之下,能够发挥出对应的效果,但是如果使用不当,或者程序过于简单,反而只是会增加复杂性。编写程序的过程中,最重要的依旧是遵循单一权责问题,加上多线程和共享数据,配合装置代码。其中,最为重要的点依旧是代码整洁。
读完这本书,给我最大的收获还是一个感受,就是我需要去做到代码整洁,而不是说我学会了代码整洁,其实在看完一遍之后,我对于其中很多的概念仍然不是很理解,但是我认为我在阅读完了书本过后,有了一个基本的去实现这些东西的触动,当然这一份触动是需要我用之后的实际行动和具体的学习来完善和加深印象的。
其实,对于我而言,其中的命名、格式、错误处理等这些模块其实在我实际的编写代码的过程中还是很具有实践意义的,在我目前的学习、编写代码的过程中,对于基本的代码整洁也有了一个基本的感触,对于自己写的程序过了一段时间我自己都觉得有问题,但是在我自己仔细地思考和具体的测试的过程中,发现其实没有问题,其实就是我之前有一个点是考虑了的,但是在后来的看代码的过程中,没有考虑进去,反而造成了影响。相反,如果,我在具体的编写的过程中,将具体的量命名具体一些,相对应的信号的作用更加详细准确一些,再者不济,添加一句注释也是能够避免的。
代码整洁,正如同书中提到的,看似是多此一举,但是这个动作确实后来效率提高的关键,其实有时候只是人们的将就和推辞导致了代码混乱,如果我们能够在一开始就做好这些的话,那么我们就能够避免后面的多余的工作。至少在一个基本的层面上能够做到代码整洁,虽然无法做到书中那般好,到那时对于之后的效率的提高还是很有帮助的。