在维护系统的时候发现有个工作经验超级丰富的同事在C#代码中使用了goto,这段代码是一个很长的方法,goto的作用是为了复用两段逻辑。当我第一次看到goto是为了复用一段C#代码的时候感觉无比诡异,总是觉得哪里不对劲。午餐的时候再次和几个同事讨论起这个问题,大家兴致很高从goto一路扯到了反模式,设计和复用。下面浅显谈谈我的一些想法。
一、反模式
有一句话说的很好,知道反模式的唯一作用就是避免使用反模式。
我的那位同事说有时候用用反模式很管用,比如因为特殊情况,你所维护的系统代码写得很长,思路跳跃,用用反模式就可以节省代码。
我的观点是,在面向对象的设计观念里复用代码的最好做法是合理抽象,运用组合或者继承,最最不济的是可以直接独立出一个上下文不是很合理的参数多一点的函数,而不是使用奇技淫巧的反模式。
反模式是一个无形的坑,你不知道什么时候维护你的代码的人会掉进你所挖的坑当中,或者为了弥补你这个坑再重新挖一个坑。
反模式用的越多,说明系统设计和抽象可能都出了问题。
二、设计
这里主要谈面向对象的系统设计。
如果你使用了面向对象语言工具进行编程,而且确实是一个工作经验丰富技术合格真正认清问题本质的开发人员,你应该有这样的觉悟和本能反应:当接到一个开发任务的时候,你会优先想到面向对象的设计,脑海中立刻会有一个抽象模型,里面可能包含了最基本的数据流的输入输出接口、核心业务模块、数据访问、表现层等等。理论上如果你学过各种方法论,什么TDD、DDD、敏捷、XP等等等等,能合理运用解决问题当然是锦上添花的事情。注意,必须要能够解决问题,否则引入的方法论越多,团队运作也越容易出现问题。如果碰到这样的团队,他们和你高谈阔论说敏捷、谈极限编程,实际工作的时候却给你“贡献”了非常垃圾的C#代码、混乱的SQL,不堪入目的JavaScript,这样的团队出现问题几乎不可避免。
一个理想状态是系统前期设计做的很充分,开发起来也相对非常容易。
但是实际的情况是,已经存在一个运行较久的系统,它被设计实现成如下这个样子了:
1、完全无视面向对象的分层和抽象,几乎看不到接口定义,实现思路不清楚,无法突出重点,代码可读性、易用性和可维护性奇差,UI逻辑和业务逻辑不分;
2、版本控制失控,一些简单的变更经常需要Branch几个版本,bug很难减少,一些临时变更往往牵涉出非常多的隐藏bug,牵一发而动全身;
3、异常处理不统一,日志记录不合理,页面出现问题经常看不到出现问题的原因,用数据库记录日志却不加以分析利用,导致数据库资源的滥用;
4、无法下手修改或者删除任何一行代码,加新功能难上加难,因为你不知道新代码往旧代码的哪一段插入比较合适,为了维护既有系统的功能,你不得不在现有的坑上再挖一个坑;
5、各种反模式是必备技能,上帝对象层出不穷,静态随处可见,方法一定要长,存储过程一定要很长,JavaScript一定要长长长,而且怎么能少了hard coding?
6、复制粘贴痕迹太严重了…
7、缓存的不合理使用,已经不止一次碰到因为缓存而造成业务数据的不正确,开发人员不认真分析,不会认清并选择合适的缓存应用场景,直接造成缓存的应用失控。
其实还有很多问题可谈。不知道大家看没看过Martin Fowler的代码重构?通常这种系统的实现就是代码重构那本书所举的反面示例的集大成者。每次我碰到要维护这种系统的时候都不禁感慨,系统的历史遗留问题总是惊人的相似,维护的开发人员的痛苦又是毫无二致的相同。
当然碰到上面的既有系统的实现,开发人员不能一上来就想当然地向现有代码中做加法,而是要一如既往地坚持面向对象的设计原则,抽象、分层、复用、重构,让你写的代码模块高内聚低耦合,逻辑清晰,易于维护。
三、复用
讲复用,首先要看你对复用的理解是什么。
如果你有面向对象基础,很多人可能会想到基类,想到抽象类,想到继承,想到方法和代码复用。
有一种曾经非常流行的想法:继承的目的是为了复用。后来的工程实践证明继承的目的根本不是复用,而是统一抽象和建模。
在我维护过的很多代码中,发现很多开发人员非常热衷于使用代码复用,类继承用的很厉害的样子,不使用3到5层的类继承好像体现不了他的编程水平。
但是,我看不到任何接口,一个变更过来,怎么适应变更呢?好吧,改方法实现,一改代码,就发现改动一处要引起多个引用的变更,从而造成心里紧张。
如何解决改动一处处处变更的恶劣影响呢?我们不禁想到了多态,想到了面向对象的原则里提到的面向接口编程,有可能还会想到组合优于继承的原则。
继承可以代码复用,这个谁都可以理解,而且效果非常明显,据我所知很多人所理解的复用就是让人少写代码,就是类继承。
但是多态呢,接口复用呢,面向切面编程呢?一个人对复用的理解有多深,我认为完全可以体现他的面向对象的编程水平。
本文转自JeffWong博客园博客,原文链接:http://www.cnblogs.com/jeffwongishandsome/archive/2013/01/13/2858624.html,如需转载请自行联系原作者