小步快跑是这样玩的(上)

来源:互联网 发布:mac画结构图工具 编辑:程序博客网 时间:2024/04/26 21:31

小步快跑是这样玩的(上)

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

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

故事是这样的,当用户登录一个网站时,网站往往需要给用户打一个招呼:“hi, XXX! ”。同时,如果此时是上午则显示“Good morning! ”,如果是下午则显示“Good afternoon! ”,除此显示“Good night! ”。对于这样一个需求我们在一个HelloWorld类中写了十来行代码: 
Java代码  收藏代码
  1. /** 
  2.  * The Refactoring's hello-world program 
  3.  * @author fangang 
  4.  */  
  5. public class HelloWorld {  
  6.     /** 
  7.      * Say hello to everyone 
  8.      * @param now 
  9.      * @param user 
  10.      * @return the words what to say 
  11.      */  
  12.     public String sayHello(Date now, String user){  
  13.         //Get current hour of day  
  14.         Calendar calendar = Calendar.getInstance();  
  15.         calendar.setTime(now);  
  16.         int hour = calendar.get(Calendar.HOUR_OF_DAY);  
  17.           
  18.         //Get the right words to say hello  
  19.         String words = null;  
  20.         if(hour>=6 && hour<12){  
  21.             words = "Good morning!";  
  22.         }else if(hour>=12 && hour<19){  
  23.             words = "Good afternoon!";  
  24.         }else{  
  25.             words = "Good night!";  
  26.         }  
  27.         words = "Hi, "+user+". "+words;  
  28.         return words;  
  29.     }  
  30. }  


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

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

Java代码  收藏代码
  1. /** 
  2.  * The Refactoring's hello-world program 
  3.  * @author fangang 
  4.  */  
  5. public class HelloWorld {  
  6.     /** 
  7.      * Say hello to everyone 
  8.      * @param now 
  9.      * @param user 
  10.      * @return the words what to say 
  11.      */  
  12.     public String sayHello(Date now, String user){  
  13.         //这里将原有的代码通过“抽取方法”抽取到3个函数中  
  14.         int hour = getHour(now);  
  15.         return getFirstGreeting(user)+getSecondGreeting(hour);  
  16.     }  
  17.       
  18.     /** 
  19.      * Get current hour of day. 
  20.      * @param now 
  21.      * @return current hour of day 
  22.      */  
  23.     private int getHour(Date now){  
  24.         Calendar calendar = Calendar.getInstance();  
  25.         calendar.setTime(now);  
  26.         return calendar.get(Calendar.HOUR_OF_DAY);  
  27.     }  
  28.       
  29.     /** 
  30.      * Get the first greeting. 
  31.      * @param user 
  32.      * @return the first greeting 
  33.      */  
  34.     private String getFirstGreeting(String user){  
  35.         return "Hi, "+user+". ";  
  36.     }  
  37.       
  38.     /** 
  39.      * Get the second greeting. 
  40.      * @param hour 
  41.      * @return the second greeting 
  42.      */  
  43.     private String getSecondGreeting(int hour){  
  44.         if(hour>=6 && hour<12){  
  45.             return "Good morning!";  
  46.         }else if(hour>=12 && hour<19){  
  47.             return "Good afternoon!";  
  48.         }else{  
  49.             return "Good night!";  
  50.         }  
  51.     }  
  52. }  


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

Java代码  收藏代码
  1. /** 
  2.  * The Refactoring's hello-world program 
  3.  * @author fangang 
  4.  */  
  5. public class HelloWorld {  
  6.     /** 
  7.      * Say hello to everyone 
  8.      * @param now 
  9.      * @param user 
  10.      * @return the words what to say 
  11.      */  
  12.     public String sayHello(Date now, String user){  
  13.         GreetingToUser greetingToUser = new GreetingToUser(user);  
  14.         GreetingAboutTime greetingAboutTime = new GreetingAboutTime(now);  
  15.         return greetingToUser.getGreeting() + greetingAboutTime.getGreeting();  
  16.     }  
  17. }  
  18.   
  19. /** 
  20.  * The greeting to user 
  21.  * @author fangang 
  22.  */  
  23. public class GreetingToUser {  
  24.     private String user;  
  25.     /** 
  26.      * The constructor with user 
  27.      * @param user 
  28.      */  
  29.     public GreetingToUser(String user){  
  30.         this.user = user;  
  31.     }  
  32.     /** 
  33.      * @return greeting to user 
  34.      */  
  35.     public String getGreeting(){  
  36.         return "Hi, "+user+". ";  
  37.     }  
  38. }  
  39.   
  40. /** 
  41.  * The greeting about time. 
  42.  * @author fangang 
  43.  */  
  44. public class GreetingAboutTime {  
  45.     private Date date;  
  46.     public GreetingAboutTime(Date date){  
  47.         this.date = date;  
  48.     }  
  49.     /** 
  50.      * @param date 
  51.      * @return the hour of day 
  52.      */  
  53.     private int getHour(Date date){  
  54.         Calendar calendar = Calendar.getInstance();  
  55.         calendar.setTime(date);  
  56.         return calendar.get(Calendar.HOUR_OF_DAY);  
  57.     }  
  58.     /** 
  59.      * @return the greeting about time 
  60.      */  
  61.     public String getGreeting(){  
  62.         int hour = getHour(date);  
  63.         if(hour>=6 && hour<12){  
  64.             return "Good morning!";  
  65.         }else if(hour>=12 && hour<19){  
  66.             return "Good afternoon!";  
  67.         }else{  
  68.             return "Good night!";  
  69.         }  
  70.     }  
  71. }  
0 0
原创粉丝点击