软件的发展规律就是这样的,起初十分简单明了,使我们可以轻松地进行合理的设计。接着开始变更,业务变得越来越复杂,程序也随之变得越来越复杂了。正是因为软件开始由简单软件向复杂软件转变,而我们的设计却没有合理地调整,最后导致了我们的系统越维护越困难,成为了不可被扣的遗留系统——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!";
}
}
}
(续)
相关文档
遗留系统:IT攻城狮永远的痛
需求变更是罪恶之源吗?
系统重构是个什么玩意儿
我们应当改变我们的设计习惯
小步快跑是这样玩的(上)
小步快跑是这样玩的(下)
代码复用应该这样做(1)
代码复用应该这样做(2)
代码复用应该这样做(3)
做好代码复用不简单(1)
特别说明:希望网友们在转载本文时,应当注明作者或出处,以示对作者的尊重,谢谢!
分享到:
相关推荐
20210123-东方证券-传媒行业微信视频号系列报告之一:小步快跑,微信视频号不是短视频.pdf
微信视频号系列报告之一:小步快跑,微信视频号不是短视频.pdf
小步快跑,快速迭代:安全运营的器术法道 安全研究 安全对抗 安全分析 物联网安全法律法规
ERP项目实施经历 虹信信息化的“小步快跑” 管理资料.doc
吉比特-603444-公司深度报告:小步快跑,高质量成长验证价值.pdf
房地产企业汇报成果ppt参考-217.《小步快跑——实现项目又快又好开发》.zip
微信视频号系列报告之一:小步快跑,微信视频号不是短视频(2021)(25页).pdf
华泰证券-电力设备与新能源行业专题研究,复合箔之二:小步快跑夯实量产之基-230525.pdf
根据小步快跑原则制订的顶推方案与实际施工顶推方案及另一种假想的顶推方案的对比计算结果表明,小步快跑顶推方案可使施工过程中的桥塔应力更加逼近理想受力状态,有利于增加桥塔的施工安全裕度及全桥结
脑海中必须时刻牢记“小步快跑,快速试错”的理念,业务说啥,就是啥,业务要怎么做,你就怎么做。另外,研发资源的投入基本和业务对等,业务需求多,人数增加,业务需求少,人数相应减少,而且团队组织也基本按功能...
时代的脚步越来越快,面对从互联网时代到人工智能时代的过渡、...营销或是运营切入,不论是小步快跑还是大步向前,数据猿将持续致力于以数据应用的视角关注报道全行业,伴 随企业共同成长,成为企业商业增长的加速器。
先打个招呼,我要介绍一个老朋友,熊节。 介绍他的重要原因是,...当年我们开发一款安卓APP,用测试驱动开发的方式,不需要真机、不需要模拟器,在 JVM 上直接跑,180秒跑完 2000+个测试用例,平均每0.09秒跑一个,我
它鼓励企业采取小步快跑的方式,逐步推进各项计划,以降低风险,确保每一步的转型都能取得实质性成效。综上所述,《新一代数字化转型信息化总体规划方案》是企业在数字化道路上的一盏明灯,它不仅为企业提供了一个...
在第 25 节、第 26 节中,我们讲了如何对一个性能计数器框架进行分析、设计与实现,并且实践了之前学过的一些设计原则和设计思想。当时我们提到,小步快跑、逐步迭
4、迭代思维:对创新流程的理解,互联网的变化太快,没有太多时间来让人做计划、做调查,所以我们可以实时的关注消费者需求,根据消费者需求的变化进行微创新,小步快跑,快速迭代(试错)。 5、流量思维:对业务...
文本为研发组织效能改进体系,以用户价值为核心,敏捷迭代,小步快跑,建立持续交付,用户反馈,功能业务闭环。 以业务为导向的跨职能合作,一段时间内享有固定的人员配置。职能主管统筹管理,与各业务负责人形成AB...
本教程详细论述了敏捷开发是以用户的需求为核心,通过不断迭代、小步快跑、循序渐进的方法进行软件产品的研发,在迭代研发过程中的产品都需要经过测试,具备可视化、可集成和可运行使用的特征
从QQ到微信,从《英雄联盟》到《王者荣耀》,腾讯公司凭借强大的产品力成为世界互联网企业中的佼佼者,其“小步快跑,试错迭代”的产品开发机制,“别让我思考”的极简主义理念,“变成白痴级用户”的用户驱动战略,...