`
fangang
  • 浏览: 881797 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
311c4c32-b171-3767-b974-d26acf661fb2
谈谈用例模型的那些事儿
浏览量:38960
767c50c5-189c-3525-a93f-5884d146ee78
一次迭代式开发的研究
浏览量:68952
03a3e133-6080-3bc8-a960-9d915ed9eabc
我们应当怎样做需求分析
浏览量:410906
753f3c56-c831-3add-ba41-b3b70d6d913f
重构,是这样干的
浏览量:93675
社区版块
存档分类
最新评论

做好代码复用不简单

阅读更多
前面我们用了那么多示例讨论了代码复用。毫无疑问,几乎所有人都明白代码复用的重要意义,知道要写好代码必须要合理地复用代码。然而,曾经有一份真挚的感情放在你面前你却没有珍惜,那就是你应该复用代码了。等你失去的时候我才后悔莫及,有木有?为什么每当我们应当复用代码的关键时刻,我们却往往选择复制粘贴呢?因为道理非常清楚但实际操作起来却困难重重,因为要实现复用必须要调整原有程序。要调整原有程序,这就不好玩了,我们就不知道该怎样应对了,还是复制粘贴来得简单快捷。

有一次,我参与了一个财务系统的研发。我在开发一个功能的时候,发现有个数值型参数,有时候在前端传过来的时候数据位数或精度会非常大,造成转型成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)
做好代码复用不简单
软件可以这样维护


特别说明:希望网友们在转载本文时,应当注明作者或出处,以示对作者的尊重,谢谢!
分享到:
评论

相关推荐

    ASP代码加密器,可以对ASP代码加密,保护你的劳动成果!

    ASP代码加密是网络开发中的一种安全措施,主要目的是保护开发者编写的ASP(Active Server Pages)源代码不被轻易查看和篡改,确保知识产权不受侵犯。ASP是一种微软公司开发的服务器端脚本语言,广泛用于创建动态网页...

    代码走查单(很详细的资料)

    - **封装**:将重复的代码封装成函数或方法,提高代码的复用性。 **9. 是否存在超过20行的方法?** - **长度控制**:过长的方法往往意味着逻辑复杂,应该考虑将其拆分成更小的模块。 - **单一职责**:每个方法应该...

    如何编写代码才能使得效率高

    合理的函数设计对于提高代码的复用性和可维护性至关重要。 1. **函数的规模尽量限制在200行以内**:过长的函数难以维护。 2. **一个函数最好仅完成一件功能**:遵循单一职责原则。 3. **函数的功能应该是可以预测的...

    一个经典的小网站代码

    6. **Generics(泛型)**:增强了类型安全,允许创建泛型类、接口和方法,提高了代码复用性。 在这个小网站的代码中,我们可以预期学习以下Web开发技术: 1. **ASP.NET Web Forms**:C# 2.0常用于开发ASP.NET Web ...

    Writing Clean Code

    3. **代码结构**:保持代码结构清晰,通过函数和类的划分实现代码复用和模块化。避免过长的函数,每个函数应只做一件事,并做好。使用适当的封装,隐藏实现细节,暴露简洁的接口。 4. **错误处理**:优雅地处理错误...

    Prentice Hall - Clean Code (Aug 2008)

    9. **重构**:持续重构代码以改进其结构,而不改变其外在行为,是保持代码质量的重要手段。 10. **代码整洁**:Martin提出了“代码整洁之道”,强调代码的整洁不仅关乎语法,还包括格式、布局和一致性,这些都是...

    eclipse JSDT

    - 提取方法:能够将一段代码提取为单独的函数,便于代码复用和维护。 5. **代码分析**: - 代码检查:JSDT内置的静态代码分析工具可以检查潜在的语法错误、未定义的变量和函数,以及不符合最佳实践的代码片段。 ...

    如何让FPGA代码看着整洁?这份资料告诉你答案

    5. 代码复用:通过编写可复用的代码模块和组件,可以大大提高开发效率。比如,可以创建通用的计数器模板或状态机模板,使得在多个项目中都可以重复使用这些功能块。 6. 精心设计always块:在编写always块时,应当...

    基于oracle的java swing简陋电影购票代码

    标题中的“基于Oracle的Java Swing简陋电影购票代码”揭示了这个项目是使用Java Swing图形用户界面库来设计的一个简单的电影购票系统,并且其数据库管理部分是基于Oracle数据库的。这个项目可能是一个教学实践或者...

    Python-用于pandasDataFrames的简单管道

    在大型数据集的处理过程中,为了提高代码的可读性和复用性,通常会采用管道(Pipeline)的概念。"Python-用于pandas DataFrames的简单管道"是一个关于如何在pandas中构建和使用DataFrame管道的教程或项目。 管道是...

    java实训个人总结报告.doc

    2. **代码复用与创新**:在互联网上查找参考资料是常见的学习方法,但重要的是要理解并消化代码,而不是简单复制。通过修改和扩展已有代码,可以加深对编程原理的理解,同时锻炼编程能力。 3. **图形用户界面(GUI...

    C语言的编译原理详解.docx

    - 这种机制允许开发者将通用的函数声明和类型定义存储在一个单独的文件中,从而简化代码管理并提高代码复用率。 2. **宏定义处理**: - 宏定义允许用户定义简单的文本替换规则。当遇到宏时,预处理器会用实际的...

    PHP备份和还原MySQL数据库代码

    注意,为了安全起见,不应在代码中明文写入数据库凭证,而应使用环境变量或者配置文件来存储这些信息。 接下来,我们讨论如何使用PHP来还原MySQL数据库。还原过程通常涉及读取SQL备份文件并执行其中的SQL语句。可以...

    结构化编程时代的--编程规则

    6. **让机器干杂活**:尽量使用循环、函数等控制结构来处理重复任务,避免手动复制粘贴代码,这有助于减少错误并提高代码复用性。 7. **加括号以避免二义性**:在涉及到运算优先级的地方,使用括号明确表达式执行...

    Becoming a Better Programmer_A Handbook for People Who Care About Code

    2. 实践、方法和态度:包括保持简单性、良好协作、代码复用以及创建可塑性代码。这部分内容强调了优秀的软件开发习惯和态度对于提升工作成果的重要性。 3. 学习的有效策略:如何高效学习、保持道德行为、寻找挑战...

    C编译器-C-Free

    1. **宏定义与预处理器**:C-Free支持预处理器指令的编写,利用宏定义可以简化代码,提高代码复用性。 2. **模板函数和泛型编程**:虽然C语言本身不支持模板,但C-Free的代码提示和补全功能可以帮助用户更好地利用...

    AllwinnerSoC-Plus说明1

    此外,SPL的ROPI(Read-Only Position Independent)特性限制了其与APP的代码复用,分离后反而让整个系统的架构更为整洁。 在配置方面,f1c100s-uboot设定了CPU主频为720MHz,AHB总线频率为200MHz,APB总线频率为...

Global site tag (gtag.js) - Google Analytics