public class Item {
public static final String SULFURAS = "Sulfuras";
public static final String AGED_BRIE = "Aged Brie";
public static final String BACKSTAGE_PASSES = "Backstage passes";
public static final String NORMAL = "Normal";
private final int sellIn;
private final int quality;
private final String name;
public static Item newInstanceWithNameSellInAndQuality(String name, int sellIn, int quality) {
if (!name.equals(SULFURAS) && (quality > 50 || quality < 0)) {
throw new IllegalArgumentException("The quality of the normal item should be between 0 and 50.");
}
return new Item(name, sellIn, quality);
}
private Item(String name, int sellIn, int quality) {
this.name = name;
this.sellIn = sellIn;
this.quality = quality;
}
public int getSellIn() {
return sellIn;
}
public Item updateSellInAndQuality() {
if (name.equals(SULFURAS)) {
return new Item(name, sellIn - 1, quality);
}
if (name.equals(AGED_BRIE)) {
return new Item(name, sellIn - 1, notGreaterThanFifty(quality + 1));
}
if (name.equals(BACKSTAGE_PASSES)) {
return new Item(name, sellIn - 1, notGreaterThanFifty(sellIn > 10 ? quality + 1 : (sellIn > 5 ? quality + 2 : (sellIn > 0 ? quality + 3 : 0))));
}
return new Item(name, sellIn - 1, notLessThanZero((sellIn <= 0) ? quality - 2 : quality - 1));
}
private int notGreaterThanFifty(int quality) {
return quality > 50 ? 50 : quality;
}
private int notLessThanZero(int quality) {
return quality <= 0 ? 0 : quality;
}
public int getQuality() {
return quality;
}
}
注意:重构的前提条件是正确的测试类
package org.katas;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
public class GildedRoseTest {
@Test
public void at_the_end_of_each_day_our_system_lowers_sellIn_and_quality_values_by_1_if_sellIn_is_greater_than_0_for_normal_items() {
Item item = Item.newInstanceWithNameSellInAndQuality(Item.NORMAL, 1, 20);
Item updatedItem = item.updateSellInAndQuality();
assertThat(updatedItem.getSellIn(), is(0));
assertThat(updatedItem.getQuality(), is(19));
}
@Test
public void once_the_sell_by_date_has_passed_quality_of_normal_items_degrades_twice_as_fast() {
Item item = Item.newInstanceWithNameSellInAndQuality(Item.NORMAL, 0, 20);
Item updatedItem = item.updateSellInAndQuality();
assertThat(updatedItem.getSellIn(), is(-1));
assertThat(updatedItem.getQuality(), is(18));
}
@Test
public void the_quality_of_normal_items_should_be_greater_than_or_equal_to_0() {
Item item = Item.newInstanceWithNameSellInAndQuality(Item.NORMAL, 0, 0);
Item updatedItem = item.updateSellInAndQuality();
assertThat(updatedItem.getSellIn(), is(-1));
assertThat(updatedItem.getQuality(), is(0));
}
@Test(expected = IllegalArgumentException.class)
public void the_quality_of_normal_items_should_be_no_more_than_50() {
Item item = Item.newInstanceWithNameSellInAndQuality(Item.NORMAL, 0, 51);
}
@Test
public void the_Aged_Brie_actually_increases_in_Quality_by_1_the_older_it_gets() {
Item item = Item.newInstanceWithNameSellInAndQuality(Item.AGED_BRIE, 0, 0);
Item updatedItem = item.updateSellInAndQuality();
assertThat(updatedItem.getSellIn(), is(-1));
assertThat(updatedItem.getQuality(), is(1));
}
@Test
public void the_quality_of_Aged_Brie_should_not_exceed_50() {
Item item = Item.newInstanceWithNameSellInAndQuality(Item.AGED_BRIE, -1, 50);
Item updatedItem = item.updateSellInAndQuality();
assertThat(updatedItem.getSellIn(), is(-2));
assertThat(updatedItem.getQuality(), is(50));
}
@Test
public void the_Sulfuras_is_a_legendary_item_and_as_such_its_Quality_is_80_and_it_never_alters() {
Item item = Item.newInstanceWithNameSellInAndQuality(Item.SULFURAS, -1, 80);
Item updatedItem = item.updateSellInAndQuality();
assertThat(updatedItem.getSellIn(), is(-2));
assertThat(updatedItem.getQuality(), is(80));
}
@Test
public void the_quality_of_backstage_passes_increases_by_1_when_the_sellIn_are_more_than_10_days() {
Item item = Item.newInstanceWithNameSellInAndQuality(Item.BACKSTAGE_PASSES, 11, 20);
Item updatedItem = item.updateSellInAndQuality();
assertThat(updatedItem.getSellIn(), is(10));
assertThat(updatedItem.getQuality(), is(21));
}
@Test
public void the_quality_of_backstage_passes_increases_by_2_when_the_sellIn_are_between_5_and_10_days() {
Item item = Item.newInstanceWithNameSellInAndQuality(Item.BACKSTAGE_PASSES, 10, 20);
Item updatedItem = item.updateSellInAndQuality();
assertThat(updatedItem.getSellIn(), is(9));
assertThat(updatedItem.getQuality(), is(22));
}
@Test
public void the_quality_of_backstage_passes_increases_by_3_when_the_sellIn_are_between_0_and_5_days() {
Item item = Item.newInstanceWithNameSellInAndQuality(Item.BACKSTAGE_PASSES, 5, 20);
Item updatedItem = item.updateSellInAndQuality();
assertThat(updatedItem.getSellIn(), is(4));
assertThat(updatedItem.getQuality(), is(23));
}
@Test
public void the_quality_of_backstage_passes_drops_to_0_after_the_concert() {
Item item = Item.newInstanceWithNameSellInAndQuality(Item.BACKSTAGE_PASSES, 0, 20);
Item updatedItem = item.updateSellInAndQuality();
assertThat(updatedItem.getSellIn(), is(-1));
assertThat(updatedItem.getQuality(), is(0));
}
@Test
public void the_quality_of_backstage_passes_is_not_greater_than_50() {
Item item = Item.newInstanceWithNameSellInAndQuality(Item.BACKSTAGE_PASSES, 1, 50);
Item updatedItem = item.updateSellInAndQuality();
assertThat(updatedItem.getSellIn(), is(0));
assertThat(updatedItem.getQuality(), is(50));
}
}
package org.katas;
public class Item {
public static final String SULFURAS = "Sulfuras";
public static final String AGED_BRIE = "Aged Brie";
public static final String BACKSTAGE_PASSES = "Backstage passes";
public static final String NORMAL = "Normal";
private final int sellIn;
private final int quality;
private static Sell sell;
public static Item newInstanceWithNameSellInAndQuality(String name, int sellIn, int quality) {
setSell(name);
return sell.newInstanceWithNameSellInAndQuality(sellIn, quality);
}
public Item(String name, int sellIn, int quality) {
this.sellIn = sellIn;
this.quality = quality;
}
public int getSellIn() {
return sellIn;
}
public static void setSell(String name) {
if(name.equals(SULFURAS)) {
sell = new SulfurasSell();
return;
}
if(name.equals(AGED_BRIE)) {
sell = new AgedBrieSell();
return;
}
if(name.equals(BACKSTAGE_PASSES)) {
sell = new BackstagePassesSell();
return;
}
sell = new NormalSell();
}
public Item updateSellInAndQuality() {
return sell.updateSellInAndQuality(sellIn, quality);
}
public int getQuality() {
return quality;
}
}
public interface Sell {
Item newInstanceWithNameSellInAndQuality(int sellIn, int quality);
Item updateSellInAndQuality(int sellIn, int quality);
}
package org.katas;
public class AgedBrieSell implements Sell {
public Item newInstanceWithNameSellInAndQuality(int sellIn, int quality) {
if (quality > 50 || quality < 0) {
throw new IllegalArgumentException("The quality of the normal item should be between 0 and 50.");
}
return new Item("Aged Brie", sellIn, quality);
}
public Item updateSellInAndQuality(int sellIn, int quality) {
return new Item("Aged Brie", sellIn - 1, notGreaterThanFifty(quality + 1));
}
private int notGreaterThanFifty(int quality) {
return quality > 50 ? 50 : quality;
}
}
package org.katas;
public class BackstagePassesSell implements Sell {
public Item newInstanceWithNameSellInAndQuality(int sellIn, int quality) {
if (quality > 50 || quality < 0) {
throw new IllegalArgumentException("The quality of the normal item should be between 0 and 50.");
}
return new Item("Backstage passes", sellIn, quality);
}
public Item updateSellInAndQuality(int sellIn, int quality) {
return new Item("Backstage passes", sellIn - 1, notGreaterThanFifty(sellIn > 10 ? quality + 1 : (sellIn > 5 ? quality + 2 : (sellIn > 0 ? quality + 3 : 0))));
}
private int notGreaterThanFifty(int quality) {
return quality > 50 ? 50 : quality;
}
}
package org.katas;
public class NormalSell implements Sell{
public Item newInstanceWithNameSellInAndQuality(int sellIn, int quality) {
if (quality > 50 || quality < 0) {
throw new IllegalArgumentException("The quality of the normal item should be between 0 and 50.");
}
return new Item("Normal", sellIn, quality);
}
public Item updateSellInAndQuality(int sellIn, int quality) {
return new Item("Normal", sellIn - 1, notLessThanZero((sellIn <= 0) ? quality - 2 : quality - 1));
}
private int notLessThanZero(int quality) {
return quality <= 0 ? 0 : quality;
}
}
package org.katas;
public class SulfurasSell implements Sell {
public Item newInstanceWithNameSellInAndQuality(int sellIn, int quality) {
return new Item("Sulfuras", sellIn, quality);
}
public Item updateSellInAndQuality(int sellIn, int quality) {
return new Item("Sulfuras", sellIn - 1, quality);
}
}
重构完成。