move goods degradation logic to rules engine

This commit is contained in:
Vladimir.Dombrovsky 2024-06-11 23:50:32 +03:00
parent 717e2a8c7b
commit a2ddb3298d
10 changed files with 256 additions and 52 deletions

View File

@ -10,7 +10,7 @@
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
<java.version>21</java.version>
<junit.jupiter.version>5.8.2</junit.jupiter.version>
<maven.maven-compiler-plugin.version>3.1</maven.maven-compiler-plugin.version>
<maven.maven-surefire-plugin.version>3.0.0-M4</maven.maven-surefire-plugin.version>

View File

@ -1,62 +1,37 @@
package com.gildedrose;
import com.gildedrose.rule.AgedBrieRule;
import com.gildedrose.rule.BackstageRule;
import com.gildedrose.rule.ConjuredRule;
import com.gildedrose.rule.NormalRule;
import com.gildedrose.rule.Rule;
import com.gildedrose.rule.SulfurasRule;
import java.util.ArrayList;
import java.util.List;
class GildedRose {
Item[] items;
List<Rule> rules;
public GildedRose(Item[] items) {
this.items = items;
rules = new ArrayList<>();
rules.add(new NormalRule());
rules.add(new AgedBrieRule());
rules.add(new BackstageRule());
rules.add(new SulfurasRule());
rules.add(new ConjuredRule());
}
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;
}
}
}
for (Item item : items) {
rules.stream()
.filter(rule -> rule.match(item))
.forEach(rule -> rule.apply(item));
}
}
}

View File

@ -0,0 +1,22 @@
package com.gildedrose.rule;
import com.gildedrose.Item;
import static com.gildedrose.rule.Goods.AGED_BRIE;
public class AgedBrieRule implements Rule {
@Override
public boolean match(Item item) {
return AGED_BRIE.equals(Goods.valueOfLabel(item.name));
}
@Override
public void apply(Item item) {
increaseQuality(item);
item.sellIn -= 1;
//code below doesn't match with requirements
if (item.sellIn < 0) {
increaseQuality(item);
}
}
}

View File

@ -0,0 +1,27 @@
package com.gildedrose.rule;
import com.gildedrose.Item;
import static com.gildedrose.rule.Goods.BACKSTAGE;
public class BackstageRule implements Rule{
@Override
public boolean match(Item item) {
return BACKSTAGE.equals(Goods.valueOfLabel(item.name));
}
@Override
public void apply(Item item) {
increaseQuality(item);
if (item.sellIn < 11) {
increaseQuality(item);
}
if (item.sellIn < 6) {
increaseQuality(item);
}
item.sellIn -= 1;
if (item.sellIn < 0) {
item.quality = 0;
}
}
}

View File

@ -0,0 +1,24 @@
package com.gildedrose.rule;
import com.gildedrose.Item;
import static com.gildedrose.rule.Goods.CONJURED;
public class ConjuredRule implements Rule {
@Override
public boolean match(Item item) {
return CONJURED.equals(Goods.valueOfLabel(item.name));
}
@Override
public void apply(Item item) {
item.sellIn--;
decreaseQuality(item);
decreaseQuality(item);
if (item.sellIn < 0) {
decreaseQuality(item);
decreaseQuality(item);
}
}
}

View File

@ -0,0 +1,23 @@
package com.gildedrose.rule;
public enum Goods {
AGED_BRIE("Aged Brie"),
BACKSTAGE("Backstage passes to a TAFKAL80ETC concert"),
SULFURAS("Sulfuras, Hand of Ragnaros"),
CONJURED("Conjured");
public final String label;
Goods(String label) {
this.label = label;
}
public static Goods valueOfLabel(String label) {
for (Goods e : values()) {
if (e.label.equals(label)) {
return e;
}
}
return null;
}
}

View File

@ -0,0 +1,19 @@
package com.gildedrose.rule;
import com.gildedrose.Item;
public class NormalRule implements Rule {
@Override
public boolean match(Item item) {
return Goods.valueOfLabel(item.name) == null;
}
@Override
public void apply(Item item) {
item.sellIn--;
decreaseQuality(item);
if (item.sellIn < 0) {
decreaseQuality(item);
}
}
}

View File

@ -0,0 +1,21 @@
package com.gildedrose.rule;
import com.gildedrose.Item;
public interface Rule {
boolean match(Item item);
void apply(Item item);
default void increaseQuality(Item item) {
if (item.quality < 50) {
item.quality += 1;
}
}
default void decreaseQuality(Item item) {
if (item.quality > 0) {
item.quality -= 1;
}
}
}

View File

@ -0,0 +1,17 @@
package com.gildedrose.rule;
import com.gildedrose.Item;
import static com.gildedrose.rule.Goods.SULFURAS;
public class SulfurasRule implements Rule {
@Override
public boolean match(Item item) {
return SULFURAS.equals(Goods.valueOfLabel(item.name));
}
@Override
public void apply(Item item) {
item.quality = 80;
}
}

View File

@ -8,10 +8,86 @@ class GildedRoseTest {
@Test
void foo() {
Item[] items = new Item[] { new Item("foo", 0, 0) };
Item[] items = new Item[]{new Item("foo", 0, 0)};
GildedRose app = new GildedRose(items);
app.updateQuality();
assertEquals("fixme", app.items[0].name);
assertEquals("foo", app.items[0].name);
}
@Test
void normalItem() {
GildedRose gildedRose = newGildedRose("normal item", 8, 30);
for (int i = 0; i < 10; i++) {
gildedRose.updateQuality();
}
assertEquals(-2, gildedRose.items[0].sellIn);
assertEquals(18, gildedRose.items[0].quality);
}
@Test
void agedBrieItem() {
GildedRose gildedRose = newGildedRose("Aged Brie", 8, 30);
for (int i = 0; i < 10; i++) {
gildedRose.updateQuality();
}
assertEquals(-2, gildedRose.items[0].sellIn);
assertEquals(42, gildedRose.items[0].quality);
}
@Test
void backstageItem() {
GildedRose gildedRose = newGildedRose("Backstage passes to a TAFKAL80ETC concert", 15, 10);
for (int i = 0; i < 15; i++) {
gildedRose.updateQuality();
}
assertEquals(0, gildedRose.items[0].sellIn);
assertEquals(40, gildedRose.items[0].quality);
}
@Test
void backstageItemExpired() {
GildedRose gildedRose = newGildedRose("Backstage passes to a TAFKAL80ETC concert", 15, 10);
for (int i = 0; i < 16; i++) {
gildedRose.updateQuality();
}
assertEquals(-1, gildedRose.items[0].sellIn);
assertEquals(0, gildedRose.items[0].quality);
}
@Test
void conjuredItem() {
GildedRose gildedRose = newGildedRose("Conjured", 8, 30);
for (int i = 0; i < 10; i++) {
gildedRose.updateQuality();
}
assertEquals(-2, gildedRose.items[0].sellIn);
assertEquals(6, gildedRose.items[0].quality);
}
@Test
void sulfurasItem() {
GildedRose gildedRose = newGildedRose("Sulfuras, Hand of Ragnaros", 8, 80);
for (int i = 0; i < 10; i++) {
gildedRose.updateQuality();
}
assertEquals(8, gildedRose.items[0].sellIn);
assertEquals(80, gildedRose.items[0].quality);
}
private GildedRose newGildedRose(String itemName, int itemSellIn, int itemQuality) {
Item[] items = new Item[]{new Item(itemName, itemSellIn, itemQuality)};
return new GildedRose(items);
}
}