TDD(测试驱动开发)

“用策略模式消除if语句”gildedrose-refactor

2020-01-02  本文已影响0人  程序员吾真本

作为一名开发人员,你接手了一个遗留系统。老板把这个系统原来所有的需求文档交给你,然后请你为该系统增加新功能。你翻开代码,看到了复杂嵌套的if语句。你打算在增加新功能前,重构一下这些代码。此时你该如何重构?

gildedrose-refactoring-kata-java

重构前代码

重构后代码

需求

嗨,欢迎来到镀金玫瑰团队。如您所知,我们是一家小旅馆,位于一线城市的黄金地段,旅馆老板艾里森(Allison)很友好。我们只销售高端商品。不过,每件商品都有一个销售剩余天数。随着时间的推移,商品的品质会不断下降。我们拥有一个可以更新库存信息的系统。一个名叫Leeroy的开发人员开发了这个系统,之后就离开了。你的任务是将新功能添加到该系统中,以便我们可以开始销售新种类的商品。首先介绍一下这个系统:

很简单,对吧?但下面的规则就更有趣了:

我们最近签约了一个魔法商品供应商,这需要对我们的系统进行更新:

重构步骤

  1. 确定重构的方向是"用策略模式消除if语句",注意不是要消灭所有的if语句,而仅仅通过面向对象的多态,来消灭掉判断商品类型的if语句
  2. 使用下面的测试决策表,为text test fixture增加测试场景,以避免遗漏测试用例
  3. 创建text based approval testing的基准输出文件golden-master.txt,来记录原始代码行为,以便与重构后的输出文件进行对比,检查重构破坏了原始代码的行为
  4. 提取针对一个item的方法updateItem(),因为好向策略模式迈进
  5. 将items[i]使用Introduce parameter提取成方法参数,以便引入接缝,注入子类,实现多态
  6. 将业务逻辑从GildedRose移动到Item类中,因为这些业务逻辑都是修改Item的属性,应该放到Item类里,另外也便于实现多态;运行TexttestFixture,对比输出
  7. 为分支添加所处理的商品名称注释,以便按商品类型抽取业务逻辑
  8. 选择一种商品,将与其相关的所有业务逻辑复制到方法的头部,以便移动到未来为该商品所创建的类中;运行TexttestFixture,对比输出
  9. 将上述商品作为Item的子类进行创建,并将复制到方法头部的业务逻辑,移动到该子类的同名方法中,进行override;运行TexttestFixture,对比输出
  10. 依此类推,循环往复,直到所有特殊商品的业务逻辑,都被移动到相应的子类中,最后Item的只剩下一般商品的业务逻辑,作为缺省业务逻辑;其间不断运行TexttestFixture,对比输出;最后,Item类中所有判断商品类型的if语句,由于使用了多态,而都被消灭掉
测试决策表

英文需求

Hi and welcome to team Gilded Rose. As you know, we are a small inn with a prime location in a prominent city ran by a friendly innkeeper named Allison. We also buy and sell only the finest goods. Unfortunately, our goods are constantly degrading in quality as they approach their sell by date. We have a system in place that updates our inventory for us. It was developed by a no-nonsense type named Leeroy, who has moved on to new adventures. Your task is to add the new feature to our system so that we can begin selling a new category of items. First an introduction to our system:

Pretty simple, right? Well this is where it gets interesting:

We have recently signed a supplier of conjured items. This requires an update to our system:

Feel free to make any changes to the UpdateQuality method and add any new code as long as everything still works correctly. However, do not alter the Item class or Items property as those belong to the goblin in the corner who will insta-rage and one-shot you as he doesn’t believe in shared code ownership (you can make the UpdateQuality method and Items property static if you like, we’ll cover for you).

上一篇 下一篇

猜你喜欢

热点阅读