对代码的理解

  这篇文章无关技术,只是从事工具开发来的一些总结,因为之前的工作是开发工具对代码进行检查,譬如静态检查和单元测试,很多人的理解不一样,有的人认为这些是必须的,因为可以形成一张网去看护我们的产品,不出事故还好,如果出事故可以快速的定位问题,然而也有人认为,我们的产品能运行,能赚钱就可以啊,为什么要投入更多的工作量来搞一些不赚钱的事情呢,其实这两种都可以理解,只是出发的角度不同,但是我觉得,如果一个公司要长久的发展,就需要稳定的产品来获得客户的信任,所以我支持第一种。本篇文章就是我工作两年来对代码的总结和一些看法(虽然我还是菜鸟,但是菜鸟还是能发表点心情嘛~),我们作为程序猿,当然和代码打交道最多,甚至每天的时间超过了和人的交流时间,所以,善待代码,写出精简漂亮的代码对我们来说是多么的重要。

  简单比复杂好

  随着软件行业的不断发展,历史遗留的程序越来越多,代码的维护成本越来越大,甚至大于开发成本。而新功能的开发又常常依赖于旧代码,阅读旧代码所花费的时间几乎要大于写新功能的代码。我前几天看了一本书,书中有这么一句话:“复杂的代码往往都是新手所写,只有经验老道的高手才能写出简单,富有表现力的代码”此话虽然说的有点夸张,可是也说明了经验的重要性。

  我们所写的代码除了让机器执行外,还需要别人来阅读。所以我们要:
  1.写让别人能读懂的代码
  2.写可扩展的代码
  3.写可测试的代码(代码应该具备可测试性,对没有可测试性的代码写测试,是浪费生命的表现)
  其中2,3点更多强调的是面向对象的设计原则。

怎样做到简单?有什么原则?

  1、DRY(Don‘t repeat yourself)

  此原则如此重要,简单来说是因为:代码越少,Bug也越少,没有重复逻辑的代码更易于维护,当你修复了一个bug,如果相同的逻辑还出现在另外一个地方,而你没意识到,你有没有觉得自己很冤?

  2、TED原则

  简洁(Terse):简洁的代码让人赏心悦目,就算是读代码也不会给人造成心理负担,如果某天你一看到没有格式、密密麻麻的c代码,我估计你会骂死那个写代码的程序员。
  具有表达力(Expressive):能用最少的代码表达你的意图,那说明你的代码是成功的,程序员就是需要严谨,不兜圈子,直接了当,这才是我们的风格
  只做一件事(Do one thing):专一,如果一个类、一个函数,只做一件事,那么在读代码的时候就不会造成思维混淆,同时可以大大提高工作效率

  3、关于DRY原则

  平时大家重构代码,一个重要的思想就是DRY。我要分享一个DRY的反例:
  项目在架构过程中会有各种各样的MODEL层,例如:DomainModel,ViewModel,DTO。很多时候这几个Model里的字段大部分是相同的,于是有人就会想到DRY原则,干脆直接用一种类型,省得粘贴复制,来回转换。
这个反例失败的根本原因在于:这几种Model职责各不相同,虽然大部分情况下内容会有重复,但是他们担当着各种不同的角色。
考虑这种场景: DomainModel有一个字段DateTime Birthday{get;set;},ViewModel同样具有DateTime Birthday{get;set;}。需求升级:要求界面不再显示生日,只需要显示是否成年。我们只需要在ViewModel中添加一个Bool IsAdult{get{return ....}}即可,DomainModel完全不用变化。

  放手去做,干掉冗余代码

  删除代码会有很多的益处--有些只是对你心情上的影响,而有些是很有实用价值的。

  1、删掉的代码永不崩溃,没有副作用
  删除掉无用的或者冗余的代码,那么与其相伴的枝节问题就不会在未来的某个时刻导致问题了。如果要进行大规模的重构或者是根据某个标准对源码进行排版的话,就无需担心已经删除的那部分代码了:它们已经没了。

  2、删掉代码,也为大脑清除记忆
  项目中的代码数量通常成千上万,不可能都记在脑中。但是看见方法名的时候,我们无需去查阅文档或者源码就可以记起该方法的作用。需要记忆的东西越少,我们的创造性就越高,删掉冗余的或者无用的代码,我们需要记忆或者关心的事情就又减少了一些。

  3、删掉的自动化测试不会失败,而且运行的飞快
  无需为不用的代码进行测试。如果某个组件只是在其测试中才会被调用,删掉它吧。这有助于解决测试中的副作用和无意中的耦合现象。还有,删除鲜有被调用的代码可使得单元测试的覆盖率提高。

  4、在写代码时就审查代码的价值
  如果你已经习惯了删除无用的代码,你会在写代码之前就问自己一句我真的需要这些代码吗?。这样你可以避免写出不是肯定会需要的代码。你还习惯于会去找寻是否已经有代码可以解决手头的问题,以此来避免重新发明轮子。这些都有助于你的项目的可维护性。

  5、它并没有真消失
  大家都在使用源码管理工具。删除掉的代码只是不再挡着你前进的道路,但是它们并没有真的消失了--它们仍然存在于代码管理工具中。你通过删除冗余和混乱获得了清晰明净,但是如果日后发现删除的代码中有闪光点,存在有价值的类和方法的话,你总是可以再把它们找回来的。

时间: 2024-11-13 08:19:46

对代码的理解的相关文章

lombok 简化java代码注解 理解

lombok 注解: lombok 提供的注解不多,可以参考官方视频的讲解和官方文档.     Lombok 注解在线帮助文档:http://projectlombok.org/features/index.    下面介绍几个我常用的 lombok 注解:         @Data   :注解在类上:提供类所有属性的 getting 和 setting 方法,此外还提供了equals.canEqual.hashCode.toString 方法         @Setter:注解在属性上:为

CodeFirst中导航属性的代码实现 理解

  导航属性是在CodeFirst中,两中数据库表之间,多对多或者1对多中表关联的属性.导航属性并不带有数据, 包括以下信息: 名称. (必需) 导航属性要导航的关联. (必需) 导航属性要导航的关联端. (必需) 对于多对多的导航属性,两张表是可选的.如果对关联一端的某实体类型定义导航属性,则不需要对关联另一端的该实体类型定义导航属性. 导航属性的数据类型是由其远程关联端的重数决定的. 重数:在关联的一端可以存在的实体类型实例的数量.关联端重数可以有以下列值之一: 一(1):表明在关联端存在且

关于阮一峰老师es6(第三版)中管道机制代码的理解浅析

最近正在学习阮一峰老师的es6(第三版)教材,在学到第七章<函数的扩展>中的箭头函数嵌套时,文中提到了一个关于“管道机制”的示例,文中源代码如下: //es6(第三版)教材中的管道机制源代码: const pipeline = (...funcs) => val => funcs.reduce((a, b) => b(a), val); const plus1 = a => a + 1; const mult2 = a => a * 2; const addThe

iOS代码签名理解

前言 做了几年iOS app coder了,对于证书的生成.使用流程烂熟于心,然而对于这套机制的原理却一直不甚理解.近来由于工作需要仔细研究了一下,特将自己的学习经验记录于此,以供大家学习指正. 问题 通常的iOS应用的签名流程是这样的(这里只是大概写一下,具体流程网上有很多): 访问钥匙串,使用“证书助理”的“从证书颁发机构请求证书”生成一个CertificateSigningRequest.certSigningRequest文件. 打开https://developer.apple.com

table中index、newindex、rawget、rawset的一段代码及理解

1 print("lua 中 table 就是一种对象的体现") 2 3 4 function string:xsplite( delimiter ) 5 local tmptb = {} 6 if self == nil or self=='' or delimiter==nil then 7 return nil 8 elseif delimiter == '' then 9 table.insert(tmptb,self) 10 return tmptb 11 else 12 s

Windows核心编程02-记事本写代码深入理解cl.exe和link.exe

接下来用记事本手写代码: 1,建一个空的记事本,敲入以下代码 #include "windows.h" int WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine, int cmdShow) { MessageBox(NULL,"HelloWorld!","Info",MB_ABORTRETRYIGNORE|MB_ICONINFORMATION); return

【Python笔记】从一段Bug代码来理解Python的Naming Rule

从Python文档关于Naming and binding的说明可知,变量名是绑定到具体对象的,从这点来看,可以把它理解为C++中的引用.考虑下面两行语句: a = 'test' a = 'test_ext' 第1行执行后,Python解释器会在内存中创建string类型的对象'test',这个对象一旦创建就不能再修改其值.赋值符号只是将变量名a绑定到这个对象上而已. 第2行执行后,同理,值为'test_ext'的string对象被创建出来,变量名a重新绑定到这个新对象上.此时,'test'对象

Simple-DQN代码的理解笔记

# tenserboard --logdir=logs ,然后打开网页127.0.1.1:6006,可以查看定义网络的神经结构. # 两个神经网络,结构相同,但是参数不一样. # 走多少步再更新,可以自己定义 # target_net 是保存很久以前的的网络的值,冻结之前的神经网络.也叫q-real # eval_net 是实时进行更新的.每走一步,更新一步. # 他的第二个神经网络的输出,就应该等于action的数目,第二层输出的,就是一个q_eval的估计值. # n_l1是神经元的数目 #

金蝶handler中 collection 代码片段理解

1,AtsOverTimeBillBatchEditHandler中collection的理解 1 SelectorItemCollection selectors = new SelectorItemCollection(); 2 //自定义集合SelectorItemCollection的定义 3 selectors.add(new SelectorItemInfo("id")); //集合selectors中添加id 4 selectors.add(new SelectorIte