前面我们用了那么多示例讨论了代码复用。毫无疑问,几乎所有人都明白代码复用的重要意义,知道要写好代码必须要合理地复用代码。然而,曾经有一份真挚的感情放在你面前你却没有珍惜,那就是你应该复用代码了。等你失去的时候我才后悔莫及,有木有?为什么每当我们应当复用代码的关键时刻,我们却往往选择复制粘贴呢?因为道理非常清楚但实际操作起来却困难重重,因为要实现复用必须要调整原有程序。要调整原有程序,这就不好玩了,我们就不知道该怎样应对了,还是复制粘贴来得简单快捷。
有一次,我参与了一个财务系统的研发。我在开发一个功能的时候,发现有个数值型参数,有时候在前端传过来的时候数据位数或精度会非常大,造成转型成Number类型的时候会出错,必须转型成BigDecimal。同时,前端传送过来的数据有可能是String类型,也可能是char[]类型。为此我进行了如下的修改:
……
Number amount
Object value = req.getParameter(“amount”);
try{
if (value ==null){
amount = null;
} else if (value instanceof Number){
amount = (Number)value;
} else if (value instanceof String){
amount = new BigDecimal((String)value).setScale(9, RoundingMode.HALF_UP);
} else if (value instanceof char[]){
amount = new BigDecimal((char[])value).setScale(9, RoundingMode.HALF_UP);
} else {
throw new MsgException("数据不是数字!”);
}
}catch(NumberFormatException nfe){
throw new MsgException("数据不是数字格式!”);
}
……
经过测试,该问题得到了修复。但在随后的开发中,我发现系统中许许多多从前端获取数字的程序都需要这段程序。如果当我们每次需要这个功能时都将这段代码拷贝过去,实现现有的功能当然没有问题,但却会为日后的维护埋下隐患。假如有一天这段程序需要调整,难道我们要到整个系统的数百份拷贝中去修改吗?道理大家都明白,关键是这样的问题却在无数软件系统中反复出现。
在这里问题的关键在于,要让这段程序为其它的程序所复用,不修改它自身是根本没有办法做到的。我们必须从现有程序中将这段程序提取出来形成一个公用函数,为其它程序所复用,然后将该程序修改成对这个公用程序的引用才行。为此我做出了如下修改:
首先运用“抽取方法”,将这段代码从其它程序中提取出来,放到工具类中形成一个静态调用函数:
/**
* @param value
* @return 根据不同的数据格式返回数字类型的数据
*/
public static Number getNumber(Object value){
if(value==null){return null;}
if(value instanceof Number){
return (Number)value;
}
try{
if(value instanceof String){
return new BigDecimal((String)value).setScale(PRECISION,ROUNDMODE);
}
if(value instanceof char[]){
return new BigDecimal((char[])value).setScale(PRECISION,ROUNDMODE);
}
}catch(NumberFormatException nfe){
throw new MsgException("数据不是数字格式!”);
}
throw new MsgException("数据不是数字!”);
}
然后将原程序改为:
……
Number amount = XxxUtil.getNumber(req.getParameter(“amount”));
……
这里,我们运用了重构中“两顶帽子”的设计方式,先在不增加新功能的情况下,调整原程序内部结构,即抽取出工具类,以此来适应新功能的需要。经过这样的调整,在实现新功能时就可以大胆复用原有代码了,复用变得不再那么困难。
然而,我们说,做好代码复用简约而不简单,它考验的是IT攻城狮的设计水平与开发能力。怎么说呢?有时候我们意识到应该复用了,但真正要写好复用真的需要下很多功夫。而每一个复用都是一个分析、设计、重构的过程。
没有经过重构的、原生态的代码是没有办法复用的,但当我们发现代码需要复用时,切忌不要使用过去那种简单粗暴的复制粘贴。合理运用重构方法,加之以仔细、认真、及时的测试,可以保证既有代码的正确,而使整个系统合理地复用起来,以提高系统的可维护性,关键是你有没有这样的意识。所以,重构是一种习惯。
然而,复用不是银弹,它不能搞定一切问题。被复用以后,如果公用的代码出现变更,甚至出现一部分客户使用旧程序,一部分客户使用新程序,应当怎么办呢?呵呵,这下好,老革命遇到了新问题。这常常让人十分头疼,而要解决这个问题,我们就进入了一个新的话题,老程序的功能扩展……(续)
相关文档
遗留系统:IT攻城狮永远的痛
需求变更是罪恶之源吗?
系统重构是个什么玩意儿
我们应当改变我们的设计习惯
小步快跑是这样玩的(上)
小步快跑是这样玩的(下)
代码复用应该这样做(1)
代码复用应该这样做(2)
代码复用应该这样做(3)
做好代码复用不简单
软件可以这样维护
特别说明:希望网友们在转载本文时,应当注明作者或出处,以示对作者的尊重,谢谢!
分享到:
相关推荐
CMMI 代码复用报告 模板 CMMI 代码复用报告 模板
c++设计模式简单使用对比-简单体会代码复用。包括虚函数的使用方法,继承等
第5章 函数和代码复用.pdf
我们在软件开发中,经常会碰到多处代码相同或...代码复用的作用也不仅是使得代码编写简单、减少工作量。本文只讨论在一个只使用delphi作为开发工具的团队如何有效的进行代码复用,如何在开发进度、软件维护之间取得平衡
python函数及代码复用学习教案.pptx
缩短开发时间的最高效方式之一,是代码复用。无论是已经写好还是属于资源库的现有代码,通过利用它,开发者和各领域的专家都能专注于自己的应用,而不再将宝贵的时间和资源用作编程。
Python课程资源,有关函数和代码的复用PPT
包含java常用的代码,可以直接拷贝。减少代码编写工作量。
利用一个demo实例来实现代码复用,以及自定义属性等
代码复用及其原则 代码复用,顾名思义就是对曾经编写过的代码的一部分甚至全部重新加以利用,从而构建新的程序。在谈及代码复用的时候,我们首先可以想到的是继承性。代码复用的原则是: 优先使用对象组合,而不是...
介绍任何编程都提出代码复用,否则话每次开发一个新程序或者写一个新功能都要全新编写的话,那就歇菜了,但是代码复用也是有好要坏,接下来的两篇文章我们将针对代码复用来
运行时代码随机化防御代码复用攻击.pdf
一个命令行Shell程序的基础框架,轻松地用C++编写自己的shell
creator中的 scrollview复用item
在javascript中,并没有类的概念,所以代码的复用,也并不局限于类式继承。javascript中创建对象的方法很多,有构造函数,可以使用new创建对象,并且可以动态的修改对象。javascript的非类式继承(可称为现代继承...
介绍本文介绍的四种代码复用模式都是最佳实践,推荐大家在编程的过程中使用。// 新对象var child = object(parent);// 测试consol
很好用很实用的matlab频分复用代码测试
设计模式可复用面向对象软件的基础 源代码 设计模式可复用面向对象软件的基础 源代码 gof
python函数及代码复用实用教案.pptx
python函数及代码复用学习教案.ppt