虽然本书所提供的实例、代码均源于java,但是不管我们是使用什么编程语言,编写出"好代码"对于一个想成为优秀的程序员都应该是最基本的。
良好的方法命名、适宜的注释、短小的方法、各种环境下的变量命名等等,这都是大师在多年编程中总结下来的经验之谈。
在网上经常会看到很多牛人是这么说的:“项目要注意可扩展、灵活性”、“要为以后的需求变更提供好的接口”、“要灵活使用设计模式”等等,仿佛各种各样的项目功能,在设计之初就已经是如此完备,能应付各种各样突如其来的需求变更,能一下子构建出如此完备的功能,更是我们这些新手所不能及,所崇拜的。
然而通读本书之后,我得到的体会则是一开始编写完成的功能都是丑陋的并不可能如此完备,不可能想的如此周到。能编写出如此功能完备的代码,也是要经过多次修改,随着需求的不断增加而完善的。作为一个优秀的程序员,对于“坏味道”的代码不会置之不理的,他们总会花更多的时间去编写“好代码”。他们在编码过程中不仅仅是完成任务,更多的时间花在编写“好代码”,最终就会出现我们所见到的更具可扩展、灵活性好,能更好的应对未来的需求变更。
可能会有不少人反对这些说法,项目在赶工阶段时间是那么的宝贵,然而就开发而言,其实真正开发的时间大约占开发总时间的30%,而绝大部分的时间都是花费在无限的BUG修改、需求变更、测试上面,也许我们多花10%的时间在构建“好代码”上面,换回来的却是不一样的。
也有人会有这样的想法,对于老板来说,能按时完成公司要求的任务就行,然而时间紧迫的情况下,我们花费如此之多的时间在将“坏味道”代码改造为“好代码”上,老板也不会赞扬,反而会对我们的编码效率、能力有着大大的怀疑。这种情况的确是大多数程序员不得不对“坏味道”代码置之不理的原因,然而大家有没有想过,我们对“坏味道”代码置之不理,将来要回来面对并收拾烂摊子的仍然是我们自己(可能有人会暗中庆幸自己已经离开,这些烂摊子有其他人去处理)。
如果当初我们多花一些时间去编写“好代码”,在今后的修改当中,会给我们带来不少省心的事情,编码也是熟能生巧的,我们花费更多的时间在编写“好代码”上,对于“好代码”我们的经验也会更多,在开发当中,也能让其他人感觉到“好代码”所带来的各种好处。对于其他的同事而言,“好代码”能让他们迅速理解代码所代表的意思,更清晰的了解到功能所起到的作用,各个函数之间的关系。
就像大师举的例子,写一篇文章,先写一个草稿,然后一遍遍的修改,最后得到一片好的文章一样,“好代码”犹如好文章,赏心悦目、条理清晰、方便阅读等。
“好代码”并非一蹴而就的,而是经过一次次重构、迭代产生的,正如编程不仅仅是一门技术,更是一门艺术。虽然我们不可能一下子就通过重构编写出“好代码”,但是随着长时间的不断练习,每一次的编写过程当中,我们都能有所体会,经验也会越来越多,那我们离编写“好代码”的优秀程序员也越来越近。
这是我个人在阅读完该书的想法,有不足之处希望各位指出,谢谢!
突然觉得应该记录一下自己今年开始准备执行的计划,也就是我从计划开始读过的书以及自己将来会阅读的书籍。每隔一段时间总结一下,自己学习到的知识,忘记的知识,对于经典的书籍应该多读几次把基础牢牢的打好。因为本人的英文其实是很差的,所以阅读的都是中文版本的书籍,呵呵。尽管有些书已经读过,且不记得读过的时间,但是经典的书籍是应该多多咀嚼几遍的,温故而知新,呵呵。
1、CLR via C#(第三版)
--2011.12.05到2012.02.29 一直都听说这本书是经典中的经典 所以读的非常慢 读完之后收获甚丰
2、你必须知道的.NET(第二版)
--2012.03.09到2012.03.26 因为看过第一版的部分文章 对于作者也甚为敬佩 本书帮我理清了CLR中部分知识点
3、编码:隐匿在计算机软硬件背后的语言
4、代码整洁之道
--2012.03.27到2012.04.07 大师级书籍 让我对于如何编写好代码有了更多的体会 好代码是经过一次次迭代而产生的 并非一蹴而就
5、重构:改善既有代码的设计
6、数据结构与算法:C#语言描述
7、程序员修炼之道:从小工到专家
8、编程珠玑(第2版)
9、深入理解计算机系统(第2版)
10、数据挖掘概念与技术(第2版)
11、高效程序员的45个习惯:敏捷开发修炼之道
12、面向对象分析与设计(第三版)
13、深入浅出设计模式(c#/java版)
14、代码大全第二版
15、设计模式:可复用面向对象软件的基础
16、编程之美
17、编译原理
18、程序员成长路线图:从入门到优秀
--2012.03.02到2012.03.09 从这本书开始到结束花了一周的时间 虽然本书中对于以兴趣编程有着负面的想法 但是却让我体会到应该花更多的时间在自己的兴趣上 证明作者的错误观点 感谢作者的负面想法以及对于成长道路的引导
19、冒号课堂:编程范式与OOP思想
20、代码之道
21、C#高级编程(第7版)
22、C#与NET4高级程序设计
23、C#高效编程:改进C#代码的50个行之有效的办法(第2版)
24、Microsoft .NET企业级应用架构设计
25、Windows核心编程(第5版)
26、C#本质论(第3版)
希望我能在2012年结束之前,把这些书都读完,加油!
C#
摘要: 自从选择购入港版Lumia800以后,一直想尝试制作一款自己的手机软件,但是寻觅了很久一直不知道从哪个方面下手(一直挣扎到底要不要做,总是找理由拖延)。终于在一个偶然的机会,我在公司查找到了一些资料,希望把它存储到手机上,然后回到家以后再详细查看,结果发现手机没有安装笔记软件,于是便有了想自己做一个笔记软件的想法,借着上个周末的休闲时间,构思了一下软件大概的功能,便开始了我第一个windows phone软件的设计。 能完成该软件的设计,要感谢Allen Lee提供的WP7有约文章,让我有对于Windows Phone有了一些了解。 该笔记软件主要适用于记录的,也提供了一些分类。软件部...
阅读全文
posted @
2012-03-20 23:39 ahl5esoft 阅读(1146) |
评论 (7) 编辑
摘要: 因为个人在业余有尝试在做一个游戏项目,所有的功能都是使用ajax的,因此要使用JSON作为媒介,然而如果是使用集成的类库进行JSON的转化,带来的影响就是一个类在传输到页面上的时候,其实仅仅只是需要其中的几个属性而已,如果嵌套的层数比较多,例如:一个类中包含其他的类或泛型或数组,这样子,数据加起来以后多出了不少。也许有人会创建一些额外的类去来处理,那的确是可以解决这种问题,但是不同的功能所使用到的数据要是个有差别的话,那么增加类则就变成了一个无底的深渊了。 很早就有这个想法要把文章写出来,可能是自己比较懒吧,总是因为公司的工作、业余游戏的开发或是其他问题没能完成这个事情,今天终于下定决心...
阅读全文
posted @
2012-02-29 14:54 ahl5esoft 阅读(2596) |
评论 (20) 编辑
摘要: 昨天跟朋友聊天,发现他们的项目数据层使用的是最基础的纯SQL语句+SqlParameter进行数据交互的,大家知道SELECT、UPDATE、CREATE对于表的依赖性比较大,然后删除语句却不一样,它的语法比较简单,大致有以下几种: 1、DELETE FROM TableName 2、DELETE FROM TableName WHERE ID = idValue 3、DELETE FROM TableName WHERE ID IN (id1, id2, id3, id4....) 于是我们要实现这个简单的功能来简化比较常用的删除就比较容易了,主要保留2个数据,1个是TableN...
阅读全文
posted @
2012-02-07 10:25 ahl5esoft 阅读(1267) |
评论 (2) 编辑
摘要: 距离上一篇文章过去了很久,因为要将模拟键盘鼠标的模块移植到公司项目里面去,在此过程中遇到了不少问题,主要的问题有如下三个: 1、由于Timer对于每个事件都是引发一个新线程,由于模拟是连续性的,这样会引发事件之间的相互干扰。 2、模拟过程中需要有一些业务数据的支持,以及在模拟结束之后需要返回模拟结果 3、模拟过程当中,如果用户操作键盘鼠标怎么办 首先我先分享一下解决以上问题,那我们先从1开始吧。 因为Timer对于每一个定时间隔的事件都是新起一个线程,这种情况下,我们的每一个步骤就没办法变成连续性的,有一些步骤可能会变成异步执行或者在某些步骤执行时间过长的情况下,又会变成颠倒顺序...
阅读全文
posted @
2011-12-21 10:56 ahl5esoft 阅读(1082) |
评论 (3) 编辑
摘要: 上一次我们利用windows API以及xml配置来模拟键盘鼠标,但是并没有对模拟中出现的逻辑错误或者异常进行处理(例如:模拟开启之后,当前程序的部分窗体或者业务逻辑上出现错误,这时我们不只要提示相应的错误,而且必须要让模拟程序将当前正常退出,以保证数据安全。),而且在窗体内部类似Label的控件也没有办法通过抓取窗体句柄或者遍历子窗体句柄来获取相应的信息,因此在一段时间的研究和整改之后,对于一些配置节点增加了ErrorTo属性以及新增Error节点,在出现逻辑错误或者异常的时候,直接跳转到对应的节点运行对应的正常退出步骤。 我设定是可将ErrorTo的属性设置在所有节点之上,但是如果子...
阅读全文
posted @
2011-11-23 10:23 ahl5esoft 阅读(1297) |
评论 (3) 编辑
摘要: 由于工作当中有部分任务需要使用到模拟键盘鼠标来完成业务的自动调用,虽然原来的同事有做了一些共用方法以及使用XML配置档来配置模拟动作流程,但是公用的方法和XML配置组合起来用的时候还是有不少的麻烦。 配置如下: 光从一些配置上,是比较难以理解的,个人觉得除了编写这个配置的本人或者使用一段时间的开发人员以外,其他开发人员需要介入修改或者重新制作配置是有一定难度的。也许大家会对业务处理有所期待,业务判断如下: 基本上就是属于对每个节点的Switch判断,通用的节点无非就那几个,但是涉及额外业务的时候,那就必须要设定一些其他的节点作为判断的依据,甚是复杂。 于是乎,在我进入公...
阅读全文
posted @
2011-11-21 10:23 ahl5esoft 阅读(1518) |
评论 (8) 编辑
摘要: 最近在研究利用api模拟键盘鼠标的动作,类似于按键精灵,然后发现只要是标签存储的值,都没办法用api抓取窗体句柄。于是乎便有了操作内存取值的想法,这就用到了另外一个api了。 因为内存寻值,有一个区间段,我们设定的是从0x00400000到0x7FFFFFFF(这些值是根据CE的区间得来的),然而如果利用for循环去遍历,代码如下:1 Stopwatch watch = new Stopwatch();2 watch.Start();3 int start = 0x00400000, end = 0x7FFFFFFF;4 for (int i = start; i < end; i++)
阅读全文
posted @
2011-11-17 13:48 ahl5esoft 阅读(2532) |
评论 (37) 编辑
摘要: 相信各位编码一段时间UI界面的朋友们,都会跟我这个新手有着一样的想法,每次界面布局控件可能不是我们在做,但是这些控件的值是需要验证的,每新增一个新的页面,页面需要验证的控件代码我们都要一一去书写,实在是很费劲,很让人烦躁啊,而且那一串串长得不得了的If/Else实在让我们难受,情何以堪啊。于是每个人都有了跃跃欲试的想法,那我们就一起来做一个简单的验证模块吧。 可能有些朋友对于微软的控件印象不好,但是我个人觉得它还是有很大的潜力的,不然也不会有那么多收费的控件,介于用户控件的基础上加上基础控件我们可以做出很理想的一套框架哦,需要一步步的往下扩展,呵呵。 首先验证嘛,其实就是对于当前控件输...
阅读全文
posted @
2011-09-30 12:58 ahl5esoft 阅读(1569) |
评论 (8) 编辑
摘要: 做开发也有将近2年的时间了,但是经验其实也不多。经历过几个小公司,数据处理层使用过基本的SQL,也有NHibernate框架。框架确实好用,省去了不少代码量,但是业务复杂的情况下,也就难以依托了,仍然需要自己手动书写SQL。业余开发项目的时候数据层使用了框架,后来改回了基础的SQL底层,原因嘛,也想说自己在重复造轮子的情况下,能有其他的收获。 原本使用泛型版本的底层基类,无法使用多态,因此也就无法使用工厂模式创建对应的SQL接口了。 原数据库基类: 1 /// <summary> 2 /// 数据库连接基类 3 /// </summary> 4 /// <type
阅读全文
posted @
2011-09-27 11:18 ahl5esoft 阅读(3113) |
评论 (20) 编辑
摘要: 在以前的2篇文章中,个人突发奇想的仿效Java中,以?替代参数,然而在应对参数重复的情况下,需要重复填写参数,实在是挺麻烦的。因为最近在学习和使用NHibernate,对于Hql中使用[:参数名]的方式可以解决重复参数的问题。因为在参数键值传递的时候使用的是Hashtable,因此我们需要通过正则匹配【":\w+"】,并截取得到对应的键,获取对应的值。代码如下: 1 Regex regMark = new Regex(@":\w+"); 2 sql = regMark.Replace(sql, s => 3 { 4 string mark = s.
阅读全文
posted @
2011-09-22 00:24 ahl5esoft 阅读(1734) |
评论 (2) 编辑
摘要: 前面的2篇关于简单介绍了仿效Java在SQL以?代替参数位置的实现方案,在编程开发中,我们都会将一些奇怪的简单的、复杂的想法,用我们本身的编程理念去实现,从粗糙到优美的每一步,都能让我们感到骄傲,虽然在别人眼中可能是一个愚蠢的、甚至是脑残的想法,但是作为一个程序员,我始终认为:“编程不仅既是一门技术,更是一门艺术;就算是最枯燥乏味的编码,我们也要以一种激情澎湃的编码行为去完成它。”,每一次尝试、实践都能让我们获益良多,尽管不是每一次尝试都是那么正确,但是起码错误以后你也能发现,原来这条路是走不通的,这就是经验。 稍微偏题了,接着我们所要讲述的内容继续下去吧。 原本我们所需要编写的SQL也许是.
阅读全文
posted @
2011-07-31 00:03 ahl5esoft 阅读(869) |
评论 (1) 编辑
摘要: 昨天写了C#中仿效Java内SQL参数以?替代的方案,但是区分了单个参数和数组参数,而且只能支持其中的一种,不能2种情况都支持。今天突然发现,原来可以利用params object[]参数的时候可以将数组当作参数传入,当传入对象类型的IsArray为true的时候,可以区分出单个参数还是数组参数,这样就可以在任何情况下都能将参数以?的形式替代。由于SQL内的参数,可以是单个参数和数组参数混合的形式,因此需要属性来区分数组参数和单个参数的下标。 1 /// <summary> 2 /// 单参数下标 3 /// </summary> 4 int ParamIndex 5
阅读全文
posted @
2011-07-27 13:09 ahl5esoft 阅读(155) |
评论 (0) 编辑
摘要: 记得以前在学习Java的时候,Java的SQL中参数用?代替,今天突发奇想就拿着项目尝试着仿效这个功能。只考虑非IN的情况下,以?挖坑替代参数。例如:SELECT name,age FROM UserInfo WHERE name = ? 代码如下: 1 /// <summary> 2 /// 转化单数参数 3 /// </summary> 4 /// <param name="sql">需要处理的Sql</param> 5 /// <param name="paramValues">参数值数组
阅读全文
posted @
2011-07-26 20:22 ahl5esoft 阅读(117) |
评论 (3) 编辑
摘要: a >> b按位运算符,数字a转化为二进制后,向左移动b位例:11 >> 2 因此:11 >> 2 == 2 => 1011向左移动2为则为10a << ba和b都为数字,数字a转化为二进制后,从右边补足b位数0 或数字a乘以2的b次方例:11 << 2 11二进制为1011,补足右边2位数后为101100 因此:11 << 2 == 44~a数字a取反-1例如: ~11 == 10 ~-10 == 9a & b是按位运算,二进制情况下如果相同位数都为1则为1否则为0例如:10 & 5 = 0 =&g
阅读全文
posted @
2011-07-19 11:09 ahl5esoft 阅读(43) |
评论 (1) 编辑