软件的发展规律就是这样的,起初十分简单明了,使我们可以轻松地进行合理的设计。接着开始变更,业务变得越来越复杂,程序也随之变得越来越复杂了。正是因为软件开始由简单软件向复杂软件转变,而我们的设计却没有合理地调整,最后导致了我们的系统越维护越困难,成为了不可被扣的遗留系统——IT攻城狮永远的痛。这就是遗留系统产生的根本原因。

因此,解决遗留系统的根本办法,就是在软件由简单软件向复杂软件转变的关键时刻,适时做出调整,使软件重新回到高质量的状态。这里,我们要做出的调整被称为重构,而做出这种调整的最佳方式,就是“小步快跑”啦。说得那么玄乎,到底什么是“小步快跑”呢?说不尽千言万语,倒不如一个简单的示例:

故事是这样的,当用户登录一个网站时,网站往往需要给用户打一个招呼:“hi, XXX! ”。同时,如果此时是上午则显示“Good morning! ”,如果是下午则显示“Good afternoon! ”,除此显示“Good night! ”。对于这样一个需求我们在一个HelloWorld类中写了十来行代码:

/** * The Refactoring's hello-world program * @author fangang */public class HelloWorld {  /**    * Say hello to everyone   * @param now     * @param user    * @return the words what to say  */   public String sayHello(Date now, String user){        //Get current hour of day     Calendar calendar = Calendar.getInstance();      calendar.setTime(now);        int hour = calendar.get(Calendar.HOUR_OF_DAY);

     //Get the right words to say hello        String words = null;     if(hour>=6 && hour<12){            words = "Good morning!";       }else if(hour>=12 && hour<19){         words = "Good afternoon!";     }else{            words = "Good night!";     }     words = "Hi, "+user+". "+words;       return words; }}

如果需求没有变更,一切都是美好的。但事情总是这样,当软件第一次提交,变更就开始了。系统总是不能直接获得用户名称,而是先获得他的userId,然后通过userId从数据库中获得用户名。后面的问候可能需要更加精细,如中午问候“Good noon! ”、傍晚问候“Good evening! ”、午夜问候“Good midnight! ”。除此之外,用户希望在一些特殊的节日,如新年问候“Happy new year! ”、情人节问候“Happy valentine’s day! ”、三八妇女节问候“Happy women’s day! ”,等等。除了已经列出的节日,他们还希望临时添加一些特殊的日子,因此问候语需要形成一个库,并支持动态添加。不仅如此,这个问候库应当支持多语言,如选择英语则显示“Good morning! ”,而选择中文则显示“上午好!”……总之,各种不同的需求被源源不断地被用户提出来,因此我们的设计师开始头脑发热、充血、开始思维混乱。是的,如果你期望你自己能一步到位搞定所有这些需求,你必然会感到千头万绪、顾此失彼,进而做出错误的设计。但如果你学会了“小步快跑”的开发模式,一切就变得没有那么复杂了。

首先,我们观察原程序,发现它包含三个相对独立的功能代码段,因此我们采用重构中的“抽取方法”,将它们分别抽取到三个函数getHour(), getFirstGreeting(), getSecondGreeting()中,并让原函数对其引用:

/** * The Refactoring's hello-world program * @author fangang */public class HelloWorld {  /**    * Say hello to everyone   * @param now     * @param user    * @return the words what to say  */   public String sayHello(Date now, String user){        //这里将原有的代码通过“抽取方法”抽取到3个函数中        int hour = getHour(now);     return getFirstGreeting(user)+getSecondGreeting(hour);   }

   /**    * Get current hour of day.    * @param now     * @return current hour of day    */   private int getHour(Date now){        Calendar calendar = Calendar.getInstance();      calendar.setTime(now);        return calendar.get(Calendar.HOUR_OF_DAY);    }

   /**    * Get the first greeting.     * @param user    * @return the first greeting     */   private String getFirstGreeting(String user){     return "Hi, "+user+". ";    }

   /**    * Get the second greeting.    * @param hour    * @return the second greeting    */   private String getSecondGreeting(int hour){       if(hour>=6 && hour<12){            return "Good morning!";     }else if(hour>=12 && hour<19){         return "Good afternoon!";       }else{            return "Good night!";       } }}

这次重构虽然使程序结构发生了较大变化,但其中真正执行的代码却没有变化,还是那些代码。随后,我们核对需求发现,用户需求分成了两个不同的分支:对用户问候语的变更,和关于时间的问候语变更。为此,我们再次对HelloWorld的程序进行了分裂,运用重构中的“抽取类”,将对用户问候的程序分裂到GreetingToUser类中,将关于时间的问候程序分裂到GreetingAboutTime类中:

/** * The Refactoring's hello-world program * @author fangang */public class HelloWorld {  /**    * Say hello to everyone   * @param now     * @param user    * @return the words what to say  */   public String sayHello(Date now, String user){        GreetingToUser greetingToUser = new GreetingToUser(user);        GreetingAboutTime greetingAboutTime = new GreetingAboutTime(now);        return greetingToUser.getGreeting() + greetingAboutTime.getGreeting();   }}

/** * The greeting to user * @author fangang */public class GreetingToUser { private String user;  /**    * The constructor with user   * @param user    */   public GreetingToUser(String user){       this.user = user;    } /**    * @return greeting to user   */   public String getGreeting(){      return "Hi, "+user+". ";    }}

/** * The greeting about time. * @author fangang */public class GreetingAboutTime {  private Date date;    public GreetingAboutTime(Date date){      this.date = date;    } /**    * @param date    * @return the hour of day    */   private int getHour(Date date){       Calendar calendar = Calendar.getInstance();      calendar.setTime(date);       return calendar.get(Calendar.HOUR_OF_DAY);    } /**    * @return the greeting about time    */   public String getGreeting(){      int hour = getHour(date);        if(hour>=6 && hour<12){            return "Good morning!";     }else if(hour>=12 && hour<19){         return "Good afternoon!";       }else{            return "Good night!";       } }}

(续)

相关文档
[url=http://fangang.iteye.com/blog/1985399]遗留系统:IT攻城狮永远的痛[/url]
[url=http://fangang.iteye.com/blog/1986749]需求变更是罪恶之源吗? [/url]
[url=http://fangang.iteye.com/blog/1988080]系统重构是个什么玩意儿[/url]
[url=http://fangang.iteye.com/blog/1998147]我们应当改变我们的设计习惯[/url]
[url=http://fangang.iteye.com/blog/1999066]小步快跑是这样玩的(上)[/url]
[url=http://fangang.iteye.com/blog/1999068]小步快跑是这样玩的(下)[/url]
[url=http://fangang.iteye.com/blog/2002581]代码复用应该这样做(1)[/url]
[url=http://fangang.iteye.com/blog/2002582]代码复用应该这样做(2)[/url]
[url=http://fangang.iteye.com/blog/2002585]代码复用应该这样做(3)[/url]
[url=http://fangang.iteye.com/blog/2010722]做好代码复用不简单(1)[/url]

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

小步快跑是这样玩的(上)相关推荐

  1. 小步快跑是这样玩的(下)

    系统重构到这一步,我们来看看用户关于时间问候语部分的变更需求:问候需要更加精细,如中午问候"Good noon! ".傍晚问候"Good evening! ". ...

  2. 大话重构连载11:小步快跑是这样玩的

    说了那么多,相信你对小步快跑的概念有了一个初步的印象,但理解还不是很深.让我们来看一看一个实际工作中的例子,来亲身感受一下什么是大布局,什么是大设计,什么是小设计. 还是回到前面那个Hello Wor ...

  3. 创业者如何小步快跑,从0开始实现自己的产品?

    2019独角兽企业重金招聘Python工程师标准>>> 某周末和学员聊完,兴起,在在行上的分类里面找自己.可是在产品里面,找来找去,完全不见踪影,反而在研发和运营里面找到了我的话题, ...

  4. log4net直切ElasticSearch,小步快跑首选

    很多小步快跑的公司,开发人员可能就3-4个,面对巨大业务压力,日连夜的赶着上线,快速试错,自然就没时间搭建一些基础设施,比如说logCenter,但初期项目不稳定,bug又多,每次都跑到生产去找日志, ...

  5. 弘辽科技:淘宝悄悄公布新规,在电商赛道小步快跑。

    疫情又来了,全国人民的生活节奏再次慢了下来.线下生活越慢,对线上服务的要求就越高,尤其是电商. 今年刚开始,淘宝在不动声色中推出了不少新规则.先是年初灰度测试了"未发货秒退款",对 ...

  6. 小步快跑,快速迭代:安全运营的器术法道

    作者 | 腾讯安全平台部 lake2 在进行安全体系建设工作的时候,人们往往容易看到的成果是新研发了一个安全系统,采用了一个新的技术,似乎做出一个系统采用一种技术就可以一劳永逸地解决某类问题了.可现实 ...

  7. 智能手机的终场战事:小步快跑进入“智慧时代”

    撰文 / 张贺飞 编辑 / 沈洁 2022年的春季发布会,照旧是一番热闹景象. OPPO.荣耀.华为.三星等品牌陆续推出新品,经历过2021年的"小阳春"后,几乎所有的主流厂商都在 ...

  8. 基于JSoup库的java爬虫开发学习——小步快跑

    因某需求,需要使用java从网页上爬取一些数据来使用,花了点时间看了一下JSoup,简单介绍一下 jsoup is a Java library for working with real-world ...

  9. 干货|软件开发,小步真能快跑吗?

    点击上方"中兴开发者社区",关注我们 每天读一篇一线开发者原创好文 作者简介 作者乐攀是非常优秀的程序员,有10多年的程序设计和开发经验,近年来致力于敏捷软件开发管理和技术实践的落 ...

最新文章

  1. Xshell配置ssh使用密钥公钥(publice key)登录
  2. Zuul:构建高可用网关之多维度限流
  3. 8个容易被忽略但不能忽略的SD-WAN功能-Vecloud
  4. c++Selection Sort选择排序的实现算法(附完整源码)
  5. 画毛毛虫代码计算机图形学,考试计算机图形学考试计算机图形学.docx
  6. 一些Vue开发小技巧,让你开发更便捷
  7. 表生成器@TableGenerator
  8. element 输入框点击事件_Element Input输入框的使用方法
  9. vb 数组属性_[读书笔记]CSAPP:7[VB]机器级表示:函数
  10. 8.微服务设计 --- 监控
  11. hdu acm 1016
  12. (附源码)ssm自助游服务系统 毕业设计 250858
  13. thinkphp5.1接入银联支付
  14. buuctf————[羊城杯 2020]login
  15. 迪进面向ConnectCore系统模块推出Digi ConnectCore语音控制软件
  16. Python 【哔哩哔哩】短视频的自动上传与发布实例演示,,同时支持抖音、快手、小红书、微视、西瓜视频、微信视频号等平台的视频自动化同步发布
  17. 微信小程序-天气预报1.0版本
  18. linux_添加一个普通用户
  19. Pywin32:Python库的简介、安装和使用攻略
  20. GO/KEGG富集分析泡泡图中为什么基因的数目是小数?

热门文章

  1. 什么是Knife4j?
  2. OC语言——基本语法和思想
  3. mysql和虚拟主机区别_mysql和虚拟主机的区别是什么
  4. matlab用plot三点画圆_怎样用Matlab 过三个点画外接圆?
  5. 调焦后焦实现不同距离成像_相机的“对焦”和“变焦”,这二者有什么区别?...
  6. 二叉树的顺序结构及实现
  7. brew cask install 解决慢的问题
  8. 2006年最值得期待的大片
  9. php h5 调用摄像头_利用html5调用本地摄像头拍照上传图片
  10. perl脚本实战总结