zoukankan      html  css  js  c++  java
  • 做好代码复用不简单

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

    有一次,我参与了一个财务系统的研发。我在开发一个功能的时候,发现有个数值型参数,有时候在前端传过来的时候数据位数或精度会非常大,造成转型成Number类型的时候会出错,必须转型成BigDecimal。同时,前端传送过来的数据有可能是String类型,也可能是char[]类型。为此我进行了如下的修改:

     1 ……
     2 Number amount
     3 Object value = req.getParameter(“amount”);
     4 try{
     5     if (value ==null){
     6         amount = null;
     7     } else if (value instanceof Number){
     8         amount = (Number)value;
     9     } else if (value instanceof String){
    10         amount = new BigDecimal((String)value).setScale(9, RoundingMode.HALF_UP);
    11     } else if (value instanceof char[]){
    12         amount = new BigDecimal((char[])value).setScale(9, RoundingMode.HALF_UP);
    13     } else {
    14         throw new MsgException("数据不是数字!”);
    15 } 16 }catch(NumberFormatException nfe){ 17 throw new MsgException("数据不是数字格式!”); 18 } 19 ……

    经过测试,该问题得到了修复。但在随后的开发中,我发现系统中许许多多从前端获取数字的程序都需要这段程序。如果当我们每次需要这个功能时都将这段代码拷贝过去,实现现有的功能当然没有问题,但却会为日后的维护埋下隐患。假如有一天这段程序需要调整,难道我们要到整个系统的数百份拷贝中去修改吗?道理大家都明白,关键是这样的问题却在无数软件系统中反复出现。

    在这里问题的关键在于,要让这段程序为其它的程序所复用,不修改它自身是根本没有办法做到的。我们必须从现有程序中将这段程序提取出来形成一个公用函数,为其它程序所复用,然后将该程序修改成对这个公用程序的引用才行。为此我做出了如下修改:

    首先运用“抽取方法”,将这段代码从其它程序中提取出来,放到工具类中形成一个静态调用函数:

     

     1 /**
     2 * @param value
     3 * @return 根据不同的数据格式返回数字类型的数据
     4 */
     5 public static Number getNumber(Object value){
     6     if(value==null){return null;}
     7     if(value instanceof Number){
     8         return (Number)value;
     9     }
    10     try{
    11         if(value instanceof String){
    12         return new BigDecimal((String)value).setScale(PRECISION,ROUNDMODE);
    13         }
    14         if(value instanceof char[]){
    15         return new BigDecimal((char[])value).setScale(PRECISION,ROUNDMODE);
    16         }
    17     }catch(NumberFormatException nfe){
    18         throw new MsgException("数据不是数字格式!”);
    19     }
    20     throw new MsgException("数据不是数字!”);
    21 }

    然后将原程序改为:

    1 ……
    2 Number amount = XxxUtil.getNumber(req.getParameter(“amount”));
    3 ……

    这里,我们运用了重构中“两顶帽子”的设计方式,先在不增加新功能的情况下,调整原程序内部结构,即抽取出工具类,以此来适应新功能的需要。经过这样的调整,在实现新功能时就可以大胆复用原有代码了,复用变得不再那么困难。

    然而,我们说,做好代码复用简约而不简单,它考验的是IT攻城狮的设计水平与开发能力。怎么说呢?有时候我们意识到应该复用了,但真正要写好复用真的需要下很多功夫。而每一个复用都是一个分析、设计、重构的过程。

    没有经过重构的、原生态的代码是没有办法复用的,但当我们发现代码需要复用时,切忌不要使用过去那种简单粗暴的复制粘贴。合理运用重构方法,加之以仔细、认真、及时的测试,可以保证既有代码的正确,而使整个系统合理地复用起来,以提高系统的可维护性,关键是你有没有这样的意识。所以,重构是一种习惯。

    然而,复用不是银弹,它不能搞定一切问题。被复用以后,如果公用的代码出现变更,甚至出现一部分客户使用旧程序,一部分客户使用新程序,应当怎么办呢?呵呵,这下好,老革命遇到了新问题。这常常让人十分头疼,而要解决这个问题,我们就进入了一个新的话题,老程序的功能扩展……(续)

    相关文档:

    遗留系统:IT攻城狮永远的痛
    需求变更是罪恶之源吗?
    系统重构是个什么玩意儿
    我们应当改变我们的设计习惯
    小步快跑是这样玩的(上)
    小步快跑是这样玩的(下)
    代码复用应该这样做(1)
    代码复用应该这样做(2)
    代码复用应该这样做(3)
    做好代码复用不简单

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

  • 相关阅读:
    openldap
    Java实现 洛谷 P1200 [USACO1.1]你的飞碟在这儿Your Ride Is He…
    Java实现 洛谷 P1200 [USACO1.1]你的飞碟在这儿Your Ride Is He…
    Java实现 洛谷 P2141 珠心算测验
    Java实现 洛谷 P2141 珠心算测验
    Java实现 洛谷 P2141 珠心算测验
    Java实现 洛谷 P2141 珠心算测验
    Java实现 洛谷 P2141 珠心算测验
    Java实现 洛谷 P1567 统计天数
    Java实现 洛谷 P1567 统计天数
  • 原文地址:https://www.cnblogs.com/mooodo/p/codeReusedIsNotEasy.html
Copyright © 2011-2022 走看看