From 8b923a6eda9acd7dd47a6fdcfeb364786988bcdf Mon Sep 17 00:00:00 2001 From: Christophe Rikelynck Date: Tue, 14 Apr 2020 15:15:14 +0200 Subject: [PATCH] added missing classes --- .../main/java/com/gildedrose/Category.java | 29 ++++++ .../main/java/com/gildedrose/GildedRose.java | 77 ++++----------- .../main/java/com/gildedrose/ItemBuilder.java | 42 ++++++++ .../java/com/gildedrose/QualityApplier.java | 97 +++++++++++++++++++ .../com/gildedrose/QualityApplierFactory.java | 23 +++++ .../test/java/com/gildedrose/ItemFixture.java | 32 ++++++ .../java/com/gildedrose/TexttestFixture.java | 37 ------- 7 files changed, 243 insertions(+), 94 deletions(-) create mode 100644 Java/src/main/java/com/gildedrose/Category.java create mode 100644 Java/src/main/java/com/gildedrose/ItemBuilder.java create mode 100644 Java/src/main/java/com/gildedrose/QualityApplier.java create mode 100644 Java/src/main/java/com/gildedrose/QualityApplierFactory.java create mode 100644 Java/src/test/java/com/gildedrose/ItemFixture.java delete mode 100644 Java/src/test/java/com/gildedrose/TexttestFixture.java diff --git a/Java/src/main/java/com/gildedrose/Category.java b/Java/src/main/java/com/gildedrose/Category.java new file mode 100644 index 00000000..e45538d5 --- /dev/null +++ b/Java/src/main/java/com/gildedrose/Category.java @@ -0,0 +1,29 @@ +package com.gildedrose; + +import java.util.Arrays; + +public enum Category { + AGED_BRIE("^Aged Brie$"), + BACKSTAGE_PASS("^Backstage passes to a TAFKAL80ETC concert$"), + SULFURAS("^Sulfuras, Hand of Ragnaros$"), + CONJURED("^Conjured Mana Cake$"), + OTHER; + + private final String nameRegex; + + Category() { + this(null); + } + + Category(String nameRegex) { + this.nameRegex = nameRegex; + } + + private boolean matches(String actualName) { + return nameRegex != null && actualName.matches(nameRegex); + } + + static Category fromName(String name) { + return Arrays.stream(Category.values()).filter(e -> e.matches(name)).findFirst().orElse(OTHER); + } +} diff --git a/Java/src/main/java/com/gildedrose/GildedRose.java b/Java/src/main/java/com/gildedrose/GildedRose.java index e6feb751..07ce3a94 100644 --- a/Java/src/main/java/com/gildedrose/GildedRose.java +++ b/Java/src/main/java/com/gildedrose/GildedRose.java @@ -1,62 +1,25 @@ package com.gildedrose; +import java.util.Arrays; + class GildedRose { - Item[] items; - public GildedRose(Item[] items) { - this.items = items; + private Item[] items; + + public GildedRose(Item[] items) { + this.items = items; + } + + public void updateQuality() { + Arrays.stream(items).forEach(this::updateQuality); + } + + void updateQuality(Item item) { + Category category = Category.fromName(item.name); + + if (category != Category.SULFURAS) { + item.sellIn = item.sellIn - 1; + QualityApplierFactory.applyQuality(item, category); } - - public void updateQuality() { - for (int i = 0; i < items.length; i++) { - if (!items[i].name.equals("Aged Brie") - && !items[i].name.equals("Backstage passes to a TAFKAL80ETC concert")) { - if (items[i].quality > 0) { - if (!items[i].name.equals("Sulfuras, Hand of Ragnaros")) { - items[i].quality = items[i].quality - 1; - } - } - } else { - if (items[i].quality < 50) { - items[i].quality = items[i].quality + 1; - - if (items[i].name.equals("Backstage passes to a TAFKAL80ETC concert")) { - if (items[i].sellIn < 11) { - if (items[i].quality < 50) { - items[i].quality = items[i].quality + 1; - } - } - - if (items[i].sellIn < 6) { - if (items[i].quality < 50) { - items[i].quality = items[i].quality + 1; - } - } - } - } - } - - if (!items[i].name.equals("Sulfuras, Hand of Ragnaros")) { - items[i].sellIn = items[i].sellIn - 1; - } - - if (items[i].sellIn < 0) { - if (!items[i].name.equals("Aged Brie")) { - if (!items[i].name.equals("Backstage passes to a TAFKAL80ETC concert")) { - if (items[i].quality > 0) { - if (!items[i].name.equals("Sulfuras, Hand of Ragnaros")) { - items[i].quality = items[i].quality - 1; - } - } - } else { - items[i].quality = items[i].quality - items[i].quality; - } - } else { - if (items[i].quality < 50) { - items[i].quality = items[i].quality + 1; - } - } - } - } - } -} \ No newline at end of file + } +} diff --git a/Java/src/main/java/com/gildedrose/ItemBuilder.java b/Java/src/main/java/com/gildedrose/ItemBuilder.java new file mode 100644 index 00000000..1b0b73bf --- /dev/null +++ b/Java/src/main/java/com/gildedrose/ItemBuilder.java @@ -0,0 +1,42 @@ +package com.gildedrose; + +class ItemBuilder { + + private String name; + private Category category; + private int sellIn; + private int quality; + + ItemBuilder() {} + + ItemBuilder name(String name) { + this.name = name; + this.category = Category.fromName(name); + return this; + } + + ItemBuilder sellIn(int sellIn) { + this.sellIn = sellIn; + return this; + } + + ItemBuilder quality(int quality) { + this.quality = quality; + return this; + } + + Item build() { + if (name == null) { + throw new IllegalArgumentException("name cannot be null"); + } + if (Category.SULFURAS != category && quality > 50) { + throw new IllegalArgumentException("quality cannot be higher than 50"); + } else if (Category.SULFURAS == category && quality != 80) { + throw new IllegalArgumentException("Sulfuras quality must always be 80"); + } + if (quality < 0) { + throw new IllegalArgumentException("quality can not be negative"); + } + return new Item(name, sellIn, quality); + } +} diff --git a/Java/src/main/java/com/gildedrose/QualityApplier.java b/Java/src/main/java/com/gildedrose/QualityApplier.java new file mode 100644 index 00000000..3b361d4a --- /dev/null +++ b/Java/src/main/java/com/gildedrose/QualityApplier.java @@ -0,0 +1,97 @@ +package com.gildedrose; + +import java.util.EnumSet; + +public interface QualityApplier { + boolean matches(Item item, Category category); + + int apply(Item item); +} + +abstract class BaseQualityApplier implements QualityApplier { + protected final EnumSet matchingCategories; + + public BaseQualityApplier(EnumSet matchingCategories) { + this.matchingCategories = matchingCategories; + } + + @Override + public boolean matches(Item item, Category category) { + return matchingCategories.contains(category); + } +} + +class DegradingQualityApplier extends BaseQualityApplier { + + private final int positiveSellInDegradeBy; + private final int negativeSellInDegradeBy; + + DegradingQualityApplier( + int positiveSellInDegradeBy, + int negativeSellInDegradeBy, + EnumSet matchingCategories) { + super(matchingCategories); + this.positiveSellInDegradeBy = positiveSellInDegradeBy; + this.negativeSellInDegradeBy = negativeSellInDegradeBy; + } + + @Override + public int apply(Item item) { + int degradeBy = item.sellIn >= 0 ? this.positiveSellInDegradeBy : negativeSellInDegradeBy; + int newQuality = item.quality - degradeBy; + if (newQuality < 0) { + newQuality = 0; + } + return newQuality; + } +} + +class IncreasingQualityApplier extends BaseQualityApplier { + + private final int increaseBy; + private final int max; + + IncreasingQualityApplier(int increaseBy, int max, EnumSet matchingCategories) { + super(matchingCategories); + this.increaseBy = increaseBy; + this.max = max; + } + + @Override + public int apply(Item item) { + int newQuality = item.quality + increaseBy; + if (newQuality >= max) { + newQuality = max; + } + return newQuality; + } +} + +class BackstagePassQualityApplier extends BaseQualityApplier { + + private final int max; + + BackstagePassQualityApplier(int max, EnumSet matchingCategories) { + super(matchingCategories); + this.max = max; + } + + @Override + public int apply(Item item) { + int newQuality; + + if (item.sellIn < 0) { + newQuality = 0; + } else if (item.sellIn < 5) { + newQuality = item.quality + 3; + } else if (item.sellIn < 10) { + newQuality = item.quality + 2; + } else { + newQuality = item.quality + 1; + } + if (newQuality >= max) { + newQuality = max; + } + return newQuality; + } +} diff --git a/Java/src/main/java/com/gildedrose/QualityApplierFactory.java b/Java/src/main/java/com/gildedrose/QualityApplierFactory.java new file mode 100644 index 00000000..def7aaba --- /dev/null +++ b/Java/src/main/java/com/gildedrose/QualityApplierFactory.java @@ -0,0 +1,23 @@ +package com.gildedrose; + +import java.util.Arrays; +import java.util.EnumSet; +import java.util.List; + +class QualityApplierFactory { + private static final List APPLIERS = + Arrays.asList( + new DegradingQualityApplier(1, 2, EnumSet.of(Category.OTHER)), + new DegradingQualityApplier(2, 2, EnumSet.of(Category.CONJURED)), + new IncreasingQualityApplier(1, 50, EnumSet.of(Category.AGED_BRIE)), + new BackstagePassQualityApplier(50, EnumSet.of(Category.BACKSTAGE_PASS))); + + private QualityApplierFactory() { + } + + static void applyQuality(Item item, Category category) { + APPLIERS.stream() + .filter(applier -> applier.matches(item, category)) + .forEach(applier -> item.quality = applier.apply(item)); + } +} diff --git a/Java/src/test/java/com/gildedrose/ItemFixture.java b/Java/src/test/java/com/gildedrose/ItemFixture.java new file mode 100644 index 00000000..91dbf1f6 --- /dev/null +++ b/Java/src/test/java/com/gildedrose/ItemFixture.java @@ -0,0 +1,32 @@ +package com.gildedrose; + +public class ItemFixture { + private static final String DEXTERITY_VEST = "+5 Dexterity Vest"; + private static final String AGED_BRIE = "Aged Brie"; + private static final String BACKSTAGE_PASS = "Backstage passes to a TAFKAL80ETC concert"; + private static final String SULFURAS = "Sulfuras, Hand of Ragnaros"; + private static final String CONJURED = "Conjured Mana Cake"; + + static ItemBuilder standard() { + return new ItemBuilder().name(DEXTERITY_VEST); + } + + static ItemBuilder agedBrie() { + return new ItemBuilder().name(AGED_BRIE); + } + + static ItemBuilder backstagePass() { + return new ItemBuilder().name(BACKSTAGE_PASS); + } + + static ItemBuilder sulfuras() { + return new ItemBuilder() + .name(SULFURAS) + .quality(80); + } + + static ItemBuilder conjured() { + return new ItemBuilder() + .name(CONJURED); + } +} diff --git a/Java/src/test/java/com/gildedrose/TexttestFixture.java b/Java/src/test/java/com/gildedrose/TexttestFixture.java deleted file mode 100644 index d059c88f..00000000 --- a/Java/src/test/java/com/gildedrose/TexttestFixture.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.gildedrose; - -public class TexttestFixture { - public static void main(String[] args) { - System.out.println("OMGHAI!"); - - Item[] items = new Item[] { - new Item("+5 Dexterity Vest", 10, 20), // - new Item("Aged Brie", 2, 0), // - new Item("Elixir of the Mongoose", 5, 7), // - new Item("Sulfuras, Hand of Ragnaros", 0, 80), // - new Item("Sulfuras, Hand of Ragnaros", -1, 80), - new Item("Backstage passes to a TAFKAL80ETC concert", 15, 20), - new Item("Backstage passes to a TAFKAL80ETC concert", 10, 49), - new Item("Backstage passes to a TAFKAL80ETC concert", 5, 49), - // this conjured item does not work properly yet - new Item("Conjured Mana Cake", 3, 6) }; - - GildedRose app = new GildedRose(items); - - int days = 2; - if (args.length > 0) { - days = Integer.parseInt(args[0]) + 1; - } - - for (int i = 0; i < days; i++) { - System.out.println("-------- day " + i + " --------"); - System.out.println("name, sellIn, quality"); - for (Item item : items) { - System.out.println(item); - } - System.out.println(); - app.updateQuality(); - } - } - -}