软件的发展规律就是这样的,起初十分简单明了,使我们可以轻松地进行合理的设计。接着开始变更,业务变得越来越复杂,程序也随之变得越来越复杂了。正是因为软件开始由简单软件向复杂软件转变,而我们的设计却没有合理地调整,最后导致了我们的系统越维护越困难,成为了不可被扣的遗留系统——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
安全运营的核心理念在于“小步快跑,快速迭代”,这意味着安全体系的建设不能只侧重于静态的、一次性的安全系统开发,而应该是一个持续的过程。这个过程中,安全运营团队需要对系统进行持续的监控、评估以及优化,以...
微信视频号系列报告之一:小步快跑,微信视频号不是短视频(2021)(25页).pdf
公司在游戏行业采用独特的研发策略,聚焦MMORPG(大型多人在线角色扮演游戏)、SLG(策略类游戏)和放置挂机类游戏三大领域,实施“小步快跑”的研发模式,通过持续迭代和优化,打造了一系列受欢迎的精品手游。...
根据小步快跑原则制订的顶推方案与实际施工顶推方案及另一种假想的顶推方案的对比计算结果表明,小步快跑顶推方案可使施工过程中的桥塔应力更加逼近理想受力状态,有利于增加桥塔的施工安全裕度及全桥结
原地摆臂小步跑有助于孩子们了解和掌握跑步中上肢和下肢动作的协调,而弓箭步压腿和手腕脚踝运动则能有效预热肌肉和关节,为快速跑作好准备,预防运动伤害。 进入基本过程,教学活动通过原地摆臂和小步跑的练习,让...
2. 50米快速跑:强调途中跑的放松自然和后蹬充分,通过专门的跑动练习(如原地摆臂、小步跑等)来强化动作,学生示例并互相评价,进行30米和50米的跑动练习,提高快速奔跑能力。 3. 弯道跑:教授弯道跑的身体姿势,...
随后的热身运动,包括头部、胸部、腿部、腰部的运动及小步跑等,能有效预防运动伤害,同时帮助学生渐入佳境。接着是快速跑练习,通过小风车游戏引出,让学生在趣味中练习快速跑的技巧。然后进行小组体验活动,如拍背...
* 原地小步跑 * 原地高抬腿 * 扶墙蹬地练习 3. 游戏:迎面接力赛跑 * 分四组进行练习 * 注意强调动作要领 教学要点 * 重点:前脚掌着地,前后摆臂 * 难点:身体平稳跑成直线 * 教师语言要清晰 * 带领学生一起...
本文是华泰证券关于电力设备与新能源行业的专题研究报告,主要聚焦于复合箔材在电池领域的应用及其产业化进程。复合箔材,特别是复合铝箔,因其优秀的安全性能在高镍三元电池系统中展现出广阔的应用前景。...
小步跑、高抬膝跑和送髋伸小腿的练习,都是帮助学生找到适合自己步幅步频比例的有效方式。同时,这些练习还能增强学生的速度、灵敏性和力量。 到了第六课次,我们将关注途中的跑步技巧。通过辅助练习和多种形式的...
在具体教学实践中,教师设计了一系列针对性的练习,如原地摆臂、小步跑、高抬腿等,以强化“蹬摆结合”的关键技术。通过游戏如“跑垒夺旗”、“勇敢者的游戏”,让学生在游戏中锻炼,增强规则意识。同时,教师还会...
进入技术学习阶段,教师会详细讲解和示范途中跑的技术,包括如何保持正确的身体姿势,如何进行有效的摆臂,以及如何进行后蹬跑、高抬腿和小步跑等辅助练习。在此过程中,教师会个别辅导,帮助学生纠正错误动作,确保...
教学组织形式多样,包括教师讲解动作要领,学生进行小步跑、接力快速跑、高抬腿跑等练习,教师实时指导纠正错误。学生以每10人为一组,共分为四组,在学校操场上进行有组织、有纪律的活动。通过接力跑和高抬腿跑的...
2. **持续改进与小步快跑**:华为提倡员工要不断改进工作方法和操作技巧,通过持之以恒的努力,实现每天进步一点点,最终达到质的飞跃。这种“小步快跑”的策略鼓励员工在实践中学习和进步,通过反复尝试和调整,...