mirror of
https://github.com/emilybache/GildedRose-Refactoring-Kata.git
synced 2026-02-15 22:41:30 +00:00
Polymorphism refactoring
This commit is contained in:
parent
3ad7c801f8
commit
3b32b9a6bf
@ -1,12 +1,18 @@
|
|||||||
package com.gildedrose;
|
package com.gildedrose;
|
||||||
|
|
||||||
import static com.gildedrose.Inventory.BACKSTAGE_PASS;
|
import com.gildedrose.domain.*;
|
||||||
import static com.gildedrose.Inventory.LEGENDARY;
|
import com.gildedrose.service.InventoryItem;
|
||||||
import static com.gildedrose.service.InventoryHelper.*;
|
|
||||||
import static java.util.stream.IntStream.range;
|
import static java.util.stream.IntStream.range;
|
||||||
import static java.util.stream.Stream.of;
|
import static java.util.stream.Stream.of;
|
||||||
|
|
||||||
class GildedRose {
|
class GildedRose {
|
||||||
|
|
||||||
|
private static final String AGED_BRIE = "Aged Brie";
|
||||||
|
private static final String LEGENDARY = "Sulfuras, Hand of Ragnaros";
|
||||||
|
private static final String CONJURED_ITEM = "Conjured Mana Cake";
|
||||||
|
private static final String BACKSTAGE_PASS = "Backstage passes to a TAFKAL80ETC concert";
|
||||||
|
|
||||||
Item[] items;
|
Item[] items;
|
||||||
|
|
||||||
GildedRose(Item[] items) {
|
GildedRose(Item[] items) {
|
||||||
@ -15,29 +21,39 @@ class GildedRose {
|
|||||||
|
|
||||||
void updateQuality() {
|
void updateQuality() {
|
||||||
of(items).forEach(item -> {
|
of(items).forEach(item -> {
|
||||||
// legendary items should not be sold
|
InventoryItem inventoryItem = inventoryFromItem(item);
|
||||||
if (itemNotLegendary(item)) item.sellIn--;
|
|
||||||
|
// reduce sellIn
|
||||||
|
item.sellIn = inventoryItem.reduceSellIn();
|
||||||
|
|
||||||
// increase quality when quality decrease is inverted
|
// increase quality when quality decrease is inverted
|
||||||
if (includesItems(item, getInventoriesWithInvertedQualityDecrease())) {
|
if (inventoryItem.qualityDecreaseInverted()) {
|
||||||
increaseQualityBelowMaximum(item);
|
item.quality = inventoryItem.increaseQualityBelowMaximum();
|
||||||
|
|
||||||
// increase backstage passes
|
|
||||||
increaseBackstagePass(item);
|
|
||||||
}
|
}
|
||||||
// decrease average (non-legendary) items
|
|
||||||
else if (itemNotLegendary(item)) {
|
|
||||||
// decrease quality based on their decrease amount
|
// decrease quality based on their decrease amount
|
||||||
range(0, getQualityDecreaseAmount(item)).forEach(i -> decreaseQualityAboveZero(item));
|
else {
|
||||||
|
range(0, inventoryItem.qualityDecreaseAmount()).forEach(i -> item.quality = inventoryItem.decreaseQualityAboveZero());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.sellIn < 0) {
|
if (item.sellIn < 0) {
|
||||||
// increase quality when aged brie
|
item.quality = inventoryItem.handleQualityAfterSellIn();
|
||||||
if (itemAgedBrie(item)) increaseQualityBelowMaximum(item);
|
|
||||||
|
|
||||||
// when not aged brie, backstage pass or legendary, decrease quality above zero
|
|
||||||
else decreaseQualityAboveZeroItemsOtherThan(item, BACKSTAGE_PASS, LEGENDARY);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private InventoryItem inventoryFromItem(Item item) {
|
||||||
|
switch (item.name) {
|
||||||
|
case AGED_BRIE:
|
||||||
|
return new AgedBrie(item);
|
||||||
|
case LEGENDARY:
|
||||||
|
return new Legendary(item);
|
||||||
|
case CONJURED_ITEM:
|
||||||
|
return new ConjuredItem(item);
|
||||||
|
case BACKSTAGE_PASS:
|
||||||
|
return new BackstagePass(item);
|
||||||
|
default:
|
||||||
|
return new DefaultItem(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,17 +0,0 @@
|
|||||||
package com.gildedrose;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@AllArgsConstructor
|
|
||||||
public enum Inventory {
|
|
||||||
AGED_BRIE("Aged Brie", true, 1),
|
|
||||||
LEGENDARY("Sulfuras, Hand of Ragnaros", false, 0),
|
|
||||||
CONJURED("Conjured Mana Cake", false, 2),
|
|
||||||
BACKSTAGE_PASS("Backstage passes to a TAFKAL80ETC concert", true, 1);
|
|
||||||
|
|
||||||
private String name;
|
|
||||||
private boolean qualityDecreaseInverted;
|
|
||||||
private int qualityDecrease;
|
|
||||||
}
|
|
||||||
29
Java/src/main/java/com/gildedrose/domain/AgedBrie.java
Normal file
29
Java/src/main/java/com/gildedrose/domain/AgedBrie.java
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package com.gildedrose.domain;
|
||||||
|
|
||||||
|
import com.gildedrose.Item;
|
||||||
|
import com.gildedrose.service.InventoryItem;
|
||||||
|
|
||||||
|
public class AgedBrie extends InventoryItem {
|
||||||
|
|
||||||
|
public AgedBrie(Item item) {
|
||||||
|
setName(item.name);
|
||||||
|
setSellIn(item.sellIn);
|
||||||
|
setQuality(item.quality);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean qualityDecreaseInverted() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int qualityDecreaseAmount() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int handleQualityAfterSellIn() {
|
||||||
|
quality = increaseQualityBelowMaximum();
|
||||||
|
return quality;
|
||||||
|
}
|
||||||
|
}
|
||||||
53
Java/src/main/java/com/gildedrose/domain/BackstagePass.java
Normal file
53
Java/src/main/java/com/gildedrose/domain/BackstagePass.java
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package com.gildedrose.domain;
|
||||||
|
|
||||||
|
import com.gildedrose.Item;
|
||||||
|
import com.gildedrose.service.InventoryItem;
|
||||||
|
|
||||||
|
public class BackstagePass extends InventoryItem {
|
||||||
|
|
||||||
|
public BackstagePass(Item item) {
|
||||||
|
setName(item.name);
|
||||||
|
setSellIn(item.sellIn);
|
||||||
|
setQuality(item.quality);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean qualityDecreaseInverted() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int qualityDecreaseAmount() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int handleQualityAfterSellIn() {
|
||||||
|
quality = 0;
|
||||||
|
return quality;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int increaseQualityBelowMaximum() {
|
||||||
|
quality = increaseQualityIfNotMaximum();
|
||||||
|
|
||||||
|
// increase backstage pass further when sellIn date approaches
|
||||||
|
quality = increaseBackstagePass();
|
||||||
|
return quality;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int increaseBackstagePass() {
|
||||||
|
if (sellIn < 10) {
|
||||||
|
quality = increaseQualityIfNotMaximum();
|
||||||
|
|
||||||
|
if (sellIn < 5) {
|
||||||
|
quality = increaseQualityIfNotMaximum();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return quality;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int increaseQualityIfNotMaximum() {
|
||||||
|
return super.increaseQualityBelowMaximum();
|
||||||
|
}
|
||||||
|
}
|
||||||
29
Java/src/main/java/com/gildedrose/domain/ConjuredItem.java
Normal file
29
Java/src/main/java/com/gildedrose/domain/ConjuredItem.java
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package com.gildedrose.domain;
|
||||||
|
|
||||||
|
import com.gildedrose.Item;
|
||||||
|
import com.gildedrose.service.InventoryItem;
|
||||||
|
|
||||||
|
public class ConjuredItem extends InventoryItem {
|
||||||
|
|
||||||
|
public ConjuredItem(Item item) {
|
||||||
|
setName(item.name);
|
||||||
|
setSellIn(item.sellIn);
|
||||||
|
setQuality(item.quality);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean qualityDecreaseInverted() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int qualityDecreaseAmount() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int handleQualityAfterSellIn() {
|
||||||
|
quality = decreaseQualityAboveZero();
|
||||||
|
return quality;
|
||||||
|
}
|
||||||
|
}
|
||||||
29
Java/src/main/java/com/gildedrose/domain/DefaultItem.java
Normal file
29
Java/src/main/java/com/gildedrose/domain/DefaultItem.java
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package com.gildedrose.domain;
|
||||||
|
|
||||||
|
import com.gildedrose.Item;
|
||||||
|
import com.gildedrose.service.InventoryItem;
|
||||||
|
|
||||||
|
public class DefaultItem extends InventoryItem {
|
||||||
|
|
||||||
|
public DefaultItem(Item item) {
|
||||||
|
setName(item.name);
|
||||||
|
setSellIn(item.sellIn);
|
||||||
|
setQuality(item.quality);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean qualityDecreaseInverted() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int qualityDecreaseAmount() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int handleQualityAfterSellIn() {
|
||||||
|
quality = decreaseQualityAboveZero();
|
||||||
|
return quality;
|
||||||
|
}
|
||||||
|
}
|
||||||
39
Java/src/main/java/com/gildedrose/domain/Legendary.java
Normal file
39
Java/src/main/java/com/gildedrose/domain/Legendary.java
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package com.gildedrose.domain;
|
||||||
|
|
||||||
|
import com.gildedrose.Item;
|
||||||
|
import com.gildedrose.service.InventoryItem;
|
||||||
|
|
||||||
|
public class Legendary extends InventoryItem {
|
||||||
|
|
||||||
|
public Legendary(Item item) {
|
||||||
|
super();
|
||||||
|
setName(item.name);
|
||||||
|
setSellIn(item.sellIn);
|
||||||
|
setQuality(item.quality);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean qualityDecreaseInverted() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int qualityDecreaseAmount() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int handleQualityAfterSellIn() {
|
||||||
|
return quality;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int decreaseQualityAboveZero() {
|
||||||
|
return quality;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int reduceSellIn() {
|
||||||
|
return sellIn;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,64 +0,0 @@
|
|||||||
package com.gildedrose.service;
|
|
||||||
|
|
||||||
import com.gildedrose.Inventory;
|
|
||||||
import com.gildedrose.Item;
|
|
||||||
|
|
||||||
import static com.gildedrose.Inventory.*;
|
|
||||||
import static java.util.stream.Stream.of;
|
|
||||||
|
|
||||||
public class InventoryHelper {
|
|
||||||
private static final int MAX_QUALITY = 50;
|
|
||||||
|
|
||||||
public static Inventory[] getInventoriesWithInvertedQualityDecrease() {
|
|
||||||
return of(Inventory.values())
|
|
||||||
.filter(Inventory::isQualityDecreaseInverted)
|
|
||||||
.distinct()
|
|
||||||
.toArray(Inventory[]::new);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void decreaseQualityAboveZeroItemsOtherThan(Item item, Inventory... inventories) {
|
|
||||||
if (!includesItems(item, inventories)) {
|
|
||||||
decreaseQualityAboveZero(item);
|
|
||||||
} else if (itemNotLegendary(item)) item.quality = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean includesItems(Item item, Inventory... inventories) {
|
|
||||||
return of(inventories).anyMatch(inventory -> item.name.equals(inventory.getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean itemNotLegendary(Item item) {
|
|
||||||
return !item.name.equals(LEGENDARY.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean itemAgedBrie(Item item) {
|
|
||||||
return item.name.equals(AGED_BRIE.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getQualityDecreaseAmount(Item item) {
|
|
||||||
return of(Inventory.values())
|
|
||||||
.filter(inventory -> inventory.getName().equals(item.name))
|
|
||||||
.findFirst()
|
|
||||||
.map(Inventory::getQualityDecrease)
|
|
||||||
.orElse(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void decreaseQualityAboveZero(Item item) {
|
|
||||||
item.quality = item.quality > 0 ? item.quality - 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void increaseQualityBelowMaximum(Item item) {
|
|
||||||
if (item.quality < MAX_QUALITY) {
|
|
||||||
item.quality++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void increaseBackstagePass(Item item) {
|
|
||||||
if (item.name.equals(BACKSTAGE_PASS.getName()) && item.sellIn < 10) {
|
|
||||||
increaseQualityBelowMaximum(item);
|
|
||||||
|
|
||||||
if (item.sellIn < 5) {
|
|
||||||
increaseQualityBelowMaximum(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
37
Java/src/main/java/com/gildedrose/service/InventoryItem.java
Normal file
37
Java/src/main/java/com/gildedrose/service/InventoryItem.java
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package com.gildedrose.service;
|
||||||
|
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Setter
|
||||||
|
public abstract class InventoryItem {
|
||||||
|
private static final int MAX_QUALITY = 50;
|
||||||
|
|
||||||
|
public String name;
|
||||||
|
public int quality;
|
||||||
|
public int sellIn;
|
||||||
|
|
||||||
|
public abstract boolean qualityDecreaseInverted();
|
||||||
|
|
||||||
|
public abstract int qualityDecreaseAmount();
|
||||||
|
|
||||||
|
public abstract int handleQualityAfterSellIn();
|
||||||
|
|
||||||
|
public int decreaseQualityAboveZero() {
|
||||||
|
quality = quality > 0 ? quality - 1 : 0;
|
||||||
|
return quality;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int increaseQualityBelowMaximum() {
|
||||||
|
if (quality < MAX_QUALITY) {
|
||||||
|
quality++;
|
||||||
|
}
|
||||||
|
return quality;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int reduceSellIn() {
|
||||||
|
sellIn--;
|
||||||
|
return sellIn;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user