前面我们讨论了小步快跑,是不是开始被雷到了,做了这么多年程序猿,原来程序可以这么开发。是的,小步快跑是一个十分新颖的概念,也许你一时半会儿还不能完全领悟,或者不能欣然接受,因为它太前卫了,与我们传统的思维大相径庭。但是,就像一部精彩的小说,我会慢慢揭开它神秘的面纱,你会慢慢领悟,进而接受。总之,小步快跑就是“活在当下”,做现在的设计,不必过多考虑将来(即使考虑,也是完全可以预见的将来),因为我们有重构。我倡导的是一种快乐的生活方式,编程是一种享受,而不是一个苦差。
然而,我们的问题并没有完全解决,因为我们面对的是遗留系统。遗留系统,就是你对它做任何事情,都要先阅读一大堆晦涩难懂的代码,然后艰难得对其进行修改。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(Capability Maturity Model Integration,能力成熟度模型集成)是衡量软件开发过程质量...
在Delphi编程环境中,代码复用是提高效率和软件质量的关键策略。代码复用不仅可以简化编码,减少工作量,还能促进团队协作,提高代码的可维护性和一致性。本文主要探讨了在只使用Delphi作为开发工具的情况下,如何...
本资料包“运用LabVIEW实现机器人中的代码复用.zip”主要关注如何利用LabVIEW提高开发效率,通过代码复用来缩短项目周期。 首先,代码复用是软件工程中的一个核心概念,旨在减少重复工作,提升开发速度和代码质量。...
在C++编程中,代码复用是提高效率和减少错误的关键。本项目“C++可复用代码——命令行控制模块”提供了一个基础框架,帮助开发者轻松构建自定义的命令行Shell程序。这个框架旨在使程序员能够专注于实现特定功能,而...
### 第5章 函数和代码复用 #### 知识点概述 本章节主要围绕着函数的概念、定义、使用以及代码复用的方式展开讨论。针对Delphi环境下的Python语言程序设计,深入剖析了如何利用函数实现更高效、灵活的编程实践。 #...
在编程领域,代码复用是提高效率和保持代码可维护性的重要原则。然而,不当的代码复用可能会引入问题。本文将探讨四种常见的代码复用模式,并分析它们的优缺点。 首先,我们来看“默认模式”的代码复用,即通过父类...
python函数及代码复用学习教案.pptx
《基于上下文的智能化代码复用推荐》这篇文章探讨了如何利用现代技术和大数据分析来提高软件开发中的代码复用效率和质量。代码复用是开发者常用的一种高效开发手段,包括复用相似功能模块、代码片段以及API等不同...
《基于上下文的智能化代码复用推荐》\n\n代码复用是软件开发中的关键实践,旨在提升开发效率和代码质量。随着互联网的发展,代码大数据的积累为智能化代码复用推荐提供了新的可能性。本文主要探讨了两个核心方向:...
这种机制使得代码复用变得简单,同时也促进了类的分层结构,有助于创建更复杂的系统。例如: ```cpp class Worker { public: void work() { // 工人的一般工作 } }; class AdvancedWorker : public Worker { ...
DRY(Don't Repeat ...总的来说,理解并正确应用DRY原则,以及掌握如何提高代码复用性,是提高软件质量、降低维护成本的关键。在实际开发中,我们需要时刻注意识别和消除代码的冗余,使我们的代码更加简洁、高效。
【运行时代码随机化防御代码复用攻击】 代码复用攻击是一种高级的恶意攻击手段,它利用了程序中已存在的可执行代码片段(称为gadgets)来构造新的恶意指令序列,绕过传统安全机制。随着攻击技术的发展,代码复用...
"jsp页面代码复用组件工具:easylayout" 指的是一种基于JavaServer Pages (JSP) 技术的代码复用工具,名为 "easylayout"。这个工具主要目的是为了提高开发效率,通过封装布局和组件,减少开发者在编写JSP页面时重复...
在本压缩包中,包含的是关于查理复用LED数码管的源代码,适用于那些希望在项目中使用这种高效驱动技术的开发者。 查理复用的基本原理是:假设我们有n个LED和n个GPIO引脚,理论上最多可以控制2^(n-1)个LED,因为不是...
以下是一个简单的MATLAB频分复用代码示例: ```matlab % 定义信号参数 x = 1544:1558; % 时间轴,范围从1544到1558,步长为1 bandwidth = 0.1; % 子信道带宽 % 生成三个独立的信号 signal1 = exp(-((x-1550)/...
补充编程模板中代码,完成如下功能:...
本教程将通过一个具体的示例——HZLoginView,深入讲解如何在Android中创建自定义View并实现代码复用及自定义属性。 首先,理解自定义View的基本步骤: 1. 创建一个新的Java类:通常,我们继承自Android的基础View...
1. **代码复用攻击**:这是一种利用程序内部已有的合法代码片段,组合成新的恶意代码的攻击方式,其目的在于绕过传统的安全防御机制。 2. **内核级代码复用攻击**:针对操作系统内核的代码复用攻击,由于内核权限高...
任何编程都提出代码复用,否则话每次开发一个新程序或者写一个新功能都要全新编写的话,那就歇菜了,但是代码复用也是有好要坏,接下来的两篇文章我们将针对代码复用来进行讨论,第一篇文避免篇,指的是要尽量避免...