> For the complete documentation index, see [llms.txt](https://ethan-lin.gitbook.io/refactoring/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ethan-lin.gitbook.io/refactoring/xiang-jin-mei-gui/11-task-8.md).

# 任务8：反转条件逻辑

现在，代码已经有了基本的结构。接下来的重构，整体的想法应该是把每种商品特定的行为搬移到各自的子类中去，怎么做到这一点呢？需要一点小技巧，那就是微调一下`if`条件逻辑。

这里有两种思路：一种是分别处理`updateSellIn()`、`updateQualityAfterExpiration()`、`updateQuality()`里的条件逻辑；一种是分别针对`isSulfuras()`、`isAgedBrie()`、`isBackstagePass()`几个分支进行移除。无论选择哪一种，我依然建议你尝试从最简单的地方入手。

```javascript
export class Item {
  ...
  passOneDay() {
    this.updateQuality()
    this.updateSellIn()
    if (this.isExpired()) {
      this.updateQualityAfterExpiration()
    }
  }

  updateSellIn() {
    if (!this.isSulfuras()) {
      this.sellIn = this.sellIn - 1
    }
  }

  ...
}
```

## 你的任务

Java：

```
git checkout task-8-if-conditions
./gradlew clean build
```

JavaScript：

```
git checkout task-8-if-conditions
npm test
```

1. 要求小步前进，每一步修改之后马上运行所有测试，确保软件行为不变

具体消除路径，你可以任选一种尝试：

1. 消除`updateSellIn()`方法中的`if`条件，把商品相关的行为搬移到特定的子类中
2. 消除`updateQualityAfterExpiration()`方法中的`if`条件，把商品相关的行为搬移到特定的子类中

或者：

1. 消除`isSulfuras()`条件判断，将相关的行为逻辑搬移到特定的子类中
2. 消除`isBackstagePass()`条件判断，将相关的行为逻辑搬移到特定的子类中

## 思考

* 反转条件逻辑的过程有没有遇到困难？
* 重构过程，有没有细心检验重构中的分支是否被测试完整覆盖？
* 体会每一步重构过程中先挑简单任务做的意义
* 选择不同的路径对于重构过程或重构结果是否会有所区别？

## 参考资料

* 《重构 2》10.3 以卫语句取代嵌套条件表达式（Replace Nested Conditional with Guard Clauses）
* 《重构 2》10.4 以多态取代条件表达式（Replace Conditional with Polymorphism）
