前面我们讨论了小步快跑,是不是开始被雷到了,做了这么多年程序猿,原来程序可以这么开发。是的,小步快跑是一个十分新颖的概念,也许你一时半会儿还不能完全领悟,或者不能欣然接受,因为它太前卫了,与我们传统的思维大相径庭。但是,就像一部精彩的小说,我会慢慢揭开它神秘的面纱,你会慢慢领悟,进而接受。总之,小步快跑就是“活在当下”,做现在的设计,不必过多考虑将来(即使考虑,也是完全可以预见的将来),因为我们有重构。我倡导的是一种快乐的生活方式,编程是一种享受,而不是一个苦差。
然而,我们的问题并没有完全解决,因为我们面对的是遗留系统。遗留系统,就是你对它做任何事情,都要先阅读一大堆晦涩难懂的代码,然后艰难得对其进行修改。IT攻城狮最大的痛不是如何面对客户异想天开的新功能,而是面对遗留系统时情何以堪。代码质量是几乎所有遗留系统共同的问题,你可以骂领导如何只重效益不重质量,你可以骂需求分析如何打酱油而不控制用户需求,你的前任代码写得如何烂。这些多说无益、人人都懂。从自己做起,写好自己的每一段代码,就是对整个项目最大的贡献。
怎样才能写好每一段代码呢?这里我不想讲太多的理论,这些理论到处都有,真不需你在这里费口舌。大家回想一下,我们在以往编写代码的过程中,有多少次在复制粘贴代码?不用说,一定是无数次,据说程序员操作最熟练的快捷键就是“ctrl+C”与“ctrl+V”。毫无疑问,我们编写的代码中有许许多多的功能是相似甚至完全相同的,关键在于你怎样去看待它。复制粘贴是最简单常用的方式,但在一个软件系统中,如果同一功能被反复地复制粘贴了,一旦这段代码需要变更时,那简直就是一种灾难。代码重复的问题普遍存在于许多遗留系统中,但我们很少会重视它,特别是在中国。然而,它就是糟糕代码的元凶,系统维护越来越困难的源头。
因此,今天我们来谈一谈代码复用。毫无疑问,我们首先应当建立起代码复用的意识。但光有意识是远远不够的,真正的考验是一个机会摆在你面前,而你要懂得该怎样做,这才是考验程序员是否优秀的地方。它需要有相当的面向对象分析与设计的理论知识(说实话,这部分是国内软件工程师最应当掌握却普遍缺失的知识,所谓的大牛就是能够用开源框架架构系统的人),与相当的分析设计经验。
不论怎样,我们先看看要解决代码复用的问题应该怎样做,然后再看看添加新代码时应该怎样复用。OK,翠花,上示例!
总体来说,第一步应该是比较代码。将功能相同或相似的代码进行比较(可以使用一些代码比较工具),然后将这些代码段中彼此相同的部分标注出来,运用“抽取方法”将其抽取到另一个函数中。这个函数中的代码,就是我们需要复用的代码。
假如这被比较的两份或者多份代码存在于同一个对象中,则将这段被抽取出来的函数作为它们共同的函数,为其它各份代码所调用。比如,有这样一段代码:
/**
* 通过DWR获得当前的request、response、session等信息
* @author fangang
*/
public class DwrContext {
/**
* @return 当前的Request
*/
public static HttpServletRequest getRequest(){
return WebContextFactory.get().getHttpServletRequest();
}
/**
* @return 当前的Response
*/
public static HttpServletResponse getResponse(){
return WebContextFactory.get().getHttpServletResponse();
}
/**
* @return 当前的Session
*/
public static HttpSession getSession(){
return WebContextFactory.get().getSession();
}
}
大家注意到在这段代码的多个函数中都有这段代码WebContextFactory.get(),也就是说这段代码是几个函数相同的部分。我们运用“抽取方法”将其抽取出来,放进getContext()函数中,而让其它的函数不再使用重复的代码,而是替换成对这个函数的调用:
/**
* 通过DWR获得当前的request、response、session等信息
* @author fangang
*/
public class DwrContext {
/**
* @return DWR的WebContext
*/
private static WebContext getContext(){
return WebContextFactory.get();
}
/**
* @return 当前的Request
*/
public static HttpServletRequest getRequest(){
return getContext().getHttpServletRequest();
}
/**
* @return 当前的Response
*/
public static HttpServletResponse getResponse(){
return getContext().getHttpServletResponse();
}
/**
* @return 当前的Session
*/
public static HttpSession getSession(){
return getContext().getSession();
}
}
这里还有一种情况也相当普遍,就是一个对象中的函数重载,比如这段代码:
/**
* 初始化工厂。根据路径读取XML文件,将XML文件中的数据装载到工厂中
* @param path XML的路径
*/
public void initFactory(String path){
// 实现读取path路径下的XML文件,然后装置工厂
}
/**
* 初始化工厂。根据路径列表依次读取XML文件,将其中的数据装载到工厂中
* @param paths 路径列表
*/
public void initFactory(String[] paths){
this.paths = paths;
for(int i=0; i<paths.length; i++){
// 实现读取paths[i]路径下的XML文件,然后装置工厂
}
}
这里加粗的部分被我省略了,其实内容很多,并且代码重复。这时我们为什么不设计成让后一个函数读取前一个函数呢?具体说就是这样:
/**
* 初始化工厂。根据路径读取XML文件,将XML文件中的数据装载到工厂中
* @param path XML的路径
*/
public void initFactory(String path){
// 实现对一个路径装置工厂
}
/**
* 初始化工厂。根据路径列表依次读取XML文件,将XML文件中的数据装载到工厂中
* @param paths 路径列表
*/
public void initFactory(String[] paths){
this.paths = paths;
for(int i=0; i<paths.length; i++){
initFactory(paths[i]);
}
}
(续)
相关文档
遗留系统:IT攻城狮永远的痛
需求变更是罪恶之源吗?
系统重构是个什么玩意儿
我们应当改变我们的设计习惯
小步快跑是这样玩的(上)
小步快跑是这样玩的(下)
代码复用应该这样做(1)
代码复用应该这样做(2)
代码复用应该这样做(3)
做好代码复用不简单(1)
特别说明:希望网友们在转载本文时,应当注明作者或出处,以示对作者的尊重,谢谢!
分享到:
相关推荐
CMMI 代码复用报告 模板 CMMI 代码复用报告 模板
第5章 函数和代码复用.pdf
我们在软件开发中,经常会碰到多处代码相同或...代码复用的作用也不仅是使得代码编写简单、减少工作量。本文只讨论在一个只使用delphi作为开发工具的团队如何有效的进行代码复用,如何在开发进度、软件维护之间取得平衡
python函数及代码复用学习教案.pptx
c++设计模式简单使用对比-简单体会代码复用。包括虚函数的使用方法,继承等
Python课程资源,有关函数和代码的复用PPT
包含java常用的代码,可以直接拷贝。减少代码编写工作量。
介绍任何编程都提出代码复用,否则话每次开发一个新程序或者写一个新功能都要全新编写的话,那就歇菜了,但是代码复用也是有好要坏,接下来的两篇文章我们将针对代码复用来
缩短开发时间的最高效方式之一,是代码复用。无论是已经写好还是属于资源库的现有代码,通过利用它,开发者和各领域的专家都能专注于自己的应用,而不再将宝贵的时间和资源用作编程。
介绍本文介绍的四种代码复用模式都是最佳实践,推荐大家在编程的过程中使用。// 新对象var child = object(parent);// 测试consol
利用一个demo实例来实现代码复用,以及自定义属性等
设计模式可复用面向对象软件的基础 源代码 设计模式可复用面向对象软件的基础 源代码 gof
很好用很实用的matlab频分复用代码测试
三种IO多路复用机制: 一:select 二:poll 三:epoll 以上三种IO多路复用的完整代码,皆可以在我的资源列表中获取下载: 资源列表:http://download.csdn.net/user/qiulanzhu
实际上,重复的代码不一定违反 DRY 原则,而且有些看似不重复的代码也有可能违反 DRY 原则。除此之外,DRY 原则与代码的复用性也有一些联系,所以,今天,我
一个命令行Shell程序的基础框架,轻松地用C++编写自己的shell
用matlab仿真时分复用的调制解调过程
代码复用及其原则 代码复用,顾名思义就是对曾经编写过的代码的一部分甚至全部重新加以利用,从而构建新的程序。在谈及代码复用的时候,我们首先可以想到的是继承性。代码复用的原则是: 优先使用对象组合,而不是...
运行时代码随机化防御代码复用攻击.pdf
实用的解码解复用源代码和mp4源代码