refactor code to have responsibility to respective items

This commit is contained in:
Kirti Deshmukh 2023-02-28 21:51:45 +05:30
parent e72499d0ee
commit 21e1a0c976
16 changed files with 375 additions and 86 deletions

View File

@ -1,6 +1,7 @@
package com.gildedrose;
import static com.gildedrose.Constants.MAX_QUALITY;
import com.gildedrose.model.Goods;
import static com.gildedrose.Constants.MIN_QUALITY;
class GildedRose {
@ -12,79 +13,16 @@ class GildedRose {
}
public void updateQuality() {
for (Item item : items) {
if (item.name.equals("Conjured Mana Cake")) {
updateQualityForConjured(item);
} else
updateQuality(item);
for (Integer i = 0; i < items.length; i++) {
Goods goods = updateQuality(items[i]);
items[i] = goods; //TODO: remove mutation
}
}
private void updateQualityForConjured(Item item) {
if (item.sellIn > 0) {
item.quality = degradeQualityBy(item.quality, 2);
} else {
item.quality = degradeQualityBy(item.quality, 4);
}
item.sellIn = item.sellIn - 1;
}
private void updateQuality(Item item) {
if (!item.name.equals("Aged Brie")
&& !item.name.equals("Backstage passes to a TAFKAL80ETC concert")) {
if (item.quality > 0) {
if (!item.name.equals("Sulfuras, Hand of Ragnaros")) {
item.quality = degradeQualityBy(item.quality, 1);
}
}
} else {
if (item.quality < 50) {
item.quality = item.quality + 1;
if (item.name.equals("Backstage passes to a TAFKAL80ETC concert")) {
if (item.sellIn < 11) {
if (item.quality < 50) {
item.quality = upgradeQualityBy(item.quality, 1);
}
}
if (item.sellIn < 6) {
if (item.quality < 50) {
item.quality = upgradeQualityBy(item.quality, 1);
}
}
}
}
}
if (!item.name.equals("Sulfuras, Hand of Ragnaros")) {
item.sellIn = item.sellIn - 1;
}
if (item.sellIn < 0) {
if (!item.name.equals("Aged Brie")) {
if (!item.name.equals("Backstage passes to a TAFKAL80ETC concert")) {
if (item.quality > 0) {
if (!item.name.equals("Sulfuras, Hand of Ragnaros")) {
item.quality = degradeQualityBy(item.quality, 1);
}
}
} else {
item.quality = 0;
}
} else {
if (item.quality < 50) {
item.quality = item.quality + 1;
}
}
}
}
private Integer degradeQualityBy(int currentQuality, int degradeBy) {
return Math.max(currentQuality - degradeBy, MIN_QUALITY);
}
private Integer upgradeQualityBy(int currentQuality, int upgradeBy) {
return Math.min(currentQuality + upgradeBy, MAX_QUALITY);
private Goods updateQuality(Item item) {
Goods goods = GoodsFactory.getGoods(item.name, item.sellIn, item.quality);
goods.updateQuality();
return goods;
}
}

View File

@ -0,0 +1,23 @@
package com.gildedrose;
import com.gildedrose.model.*;
public class GoodsFactory {
public static Goods getGoods(String name, int initialSellIn, int initialQuality) {
switch (name) {
case "Aged Brie":
return new AgedBrie(initialSellIn, initialQuality);
case "Conjured Mana Cake":
return new Conjured(initialSellIn, initialQuality);
case "Sulfuras, Hand of Ragnaros":
return new Sulfuras(initialSellIn, initialQuality);
case "Backstage passes to a TAFKAL80ETC concert":
return new BackstagePasses(initialSellIn, initialQuality);
default:
return new NormalItem(name, initialSellIn, initialQuality);
}
}
}

View File

@ -14,8 +14,8 @@ public class Item {
this.quality = quality;
}
@Override
public String toString() {
@Override
public String toString() {
return this.name + ", " + this.sellIn + ", " + this.quality;
}
}

View File

@ -0,0 +1,28 @@
package com.gildedrose.model;
import static com.gildedrose.Constants.MAX_QUALITY;
public class AgedBrie extends Goods {
public static final String AGED_BRIE = "Aged Brie";
public AgedBrie(int sellIn, int quality) {
super(AGED_BRIE, sellIn, quality);
}
@Override
public void updateQuality() {
sellInPasses();
upgradeQuality();
if (sellIn < 0) {
upgradeQuality();
}
}
private void upgradeQuality() {
quality = Math.min(quality + 1, MAX_QUALITY);
}
}

View File

@ -0,0 +1,40 @@
package com.gildedrose.model;
import static com.gildedrose.Constants.MAX_QUALITY;
import static com.gildedrose.Constants.MIN_QUALITY;
public class BackstagePasses extends Goods{
public BackstagePasses( int sellIn, int quality) {
super("Backstage passes to a TAFKAL80ETC concert", sellIn, quality);
}
@Override
public void updateQuality() {
if(isSellInLessThanOrEquals(0)) {
degradeQualityToZero();
}
else if(isSellInLessThanOrEquals(5)) {
upgradeQuality(3);
}
else if (isSellInLessThanOrEquals(10)) {
upgradeQuality(2);
} else {
upgradeQuality(1);
}
sellInPasses();
}
private boolean isSellInLessThanOrEquals(int numberOfDays) {
return sellIn <= numberOfDays;
}
private void upgradeQuality(int byValue) {
quality = Math.min(quality + byValue, MAX_QUALITY);
}
private void degradeQualityToZero() {
quality = MIN_QUALITY;
}
}

View File

@ -0,0 +1,24 @@
package com.gildedrose.model;
import static com.gildedrose.Constants.MIN_QUALITY;
public class Conjured extends Goods {
public Conjured(int sellIn, int quality) {
super("Conjured Mana Cake", sellIn, quality);
}
@Override
public void updateQuality() {
if (sellIn > 0) {
degradeQualityBy(2);
} else {
degradeQualityBy(4);
}
sellInPasses();
}
private void degradeQualityBy(int degradeBy) {
quality = Math.max(quality - degradeBy, MIN_QUALITY);
}
}

View File

@ -0,0 +1,15 @@
package com.gildedrose.model;
import com.gildedrose.Item;
public abstract class Goods extends Item {
public Goods(String name, int sellIn, int quality) {
super(name, sellIn, quality);
}
public abstract void updateQuality();
public void sellInPasses() {
sellIn = sellIn - 1;
}
}

View File

@ -0,0 +1,23 @@
package com.gildedrose.model;
import static com.gildedrose.Constants.MIN_QUALITY;
public class NormalItem extends Goods {
public NormalItem(String name, int sellIn, int quality) {
super(name, sellIn, quality);
}
@Override
public void updateQuality() {
sellInPasses();
degradeQuality();
if (sellIn < 0) {
degradeQuality();
}
}
private void degradeQuality() {
quality = Math.max(quality - 1, MIN_QUALITY);
}
}

View File

@ -0,0 +1,13 @@
package com.gildedrose.model;
public class Sulfuras extends Goods {
public Sulfuras(int sellIn, int quality) {
super("Sulfuras, Hand of Ragnaros", sellIn, quality);
}
@Override
public void updateQuality() {
// do nothing
}
}

View File

@ -1,6 +1,5 @@
package com.gildedrose;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

View File

@ -4,17 +4,17 @@ 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) };
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);

View File

@ -0,0 +1,39 @@
package com.gildedrose.model;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertEquals;
class AgedBrieTest {
private static Stream<Arguments> provideInputWhereSellInDayPassesByOneDay() {
return Stream.of(
// 3. Aged Brie
// 3.a Before sellIn
Arguments.of(new AgedBrie(2, 0), "Aged Brie", 1, 1),
Arguments.of(new AgedBrie(1, 0), "Aged Brie", 0, 1),
Arguments.of(new AgedBrie(1, 50), "Aged Brie", 0, 50),
//3.b After sellIn
Arguments.of(new AgedBrie(0, 50), "Aged Brie", -1, 50),
Arguments.of(new AgedBrie(0, 48), "Aged Brie", -1, 50));
}
@ParameterizedTest
@MethodSource("provideInputWhereSellInDayPassesByOneDay")
void shouldDegradeQualityForAnItem(AgedBrie agedBrie, String expectedName, int expectedSellIn, int expectedQuality) {
agedBrie.updateQuality();
assertEquals(expectedName, agedBrie.name);
assertEquals(expectedSellIn, agedBrie.sellIn);
assertEquals(expectedQuality, agedBrie.quality);
}
}

View File

@ -0,0 +1,37 @@
package com.gildedrose.model;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.*;
class BackstagePassesTest {
private static Stream<Arguments> provideInputWhereSellInDayPassesByOneDay() {
return Stream.of(
//5. "Backstage passes to a TAFKAL80ETC concert"
//5.a Before sellIn
Arguments.of(new BackstagePasses(15, 20), "Backstage passes to a TAFKAL80ETC concert", 14, 21),
Arguments.of(new BackstagePasses(10, 49), "Backstage passes to a TAFKAL80ETC concert", 9, 50),
Arguments.of(new BackstagePasses(10, 49), "Backstage passes to a TAFKAL80ETC concert", 9, 50),
Arguments.of(new BackstagePasses(10, 48), "Backstage passes to a TAFKAL80ETC concert", 9, 50),
Arguments.of(new BackstagePasses(5, 47), "Backstage passes to a TAFKAL80ETC concert", 4, 50),
//5.b After sellIn
Arguments.of(new BackstagePasses(0, 47), "Backstage passes to a TAFKAL80ETC concert", -1, 0));
}
@ParameterizedTest
@MethodSource("provideInputWhereSellInDayPassesByOneDay")
void shouldDegradeQualityForAnItem(BackstagePasses backstagePasses, String expectedName, int expectedSellIn, int expectedQuality) {
backstagePasses.updateQuality();
assertEquals(expectedName, backstagePasses.name);
assertEquals(expectedSellIn, backstagePasses.sellIn);
assertEquals(expectedQuality, backstagePasses.quality);
}
}

View File

@ -0,0 +1,36 @@
package com.gildedrose.model;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertEquals;
class ConjuredTest {
private static Stream<Arguments> provideInputWhereSellInDayPassesByOneDay() {
return Stream.of(
//2. Conjured item
//2.a Before sellIn
Arguments.of(new Conjured(1, 10), "Conjured Mana Cake", 0, 8),
Arguments.of(new Conjured(1, 0), "Conjured Mana Cake", 0, 0),
//2.b After sellIn
Arguments.of(new Conjured(0, 0), "Conjured Mana Cake", -1, 0),
Arguments.of(new Conjured(0, 10), "Conjured Mana Cake", -1, 6));
}
@ParameterizedTest
@MethodSource("provideInputWhereSellInDayPassesByOneDay")
void shouldDegradeQualityForAnItem(Conjured conjured, String expectedName, int expectedSellIn, int expectedQuality) {
conjured.updateQuality();
assertEquals(expectedName, conjured.name);
assertEquals(expectedSellIn, conjured.sellIn);
assertEquals(expectedQuality, conjured.quality);
}
}

View File

@ -0,0 +1,38 @@
package com.gildedrose.model;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertEquals;
class NormalItemTest {
private static Stream<Arguments> provideInputWhereSellInDayPassesByOneDay() {
return Stream.of(
// 1. Normal Item
// 1.a Before sellIn
Arguments.of(new NormalItem("Normal Item", 1, 0), "Normal Item", 0, 0),
Arguments.of(new NormalItem("Normal Item", 1, 10), "Normal Item", 0, 9),
//1.b After sellIn
Arguments.of(new NormalItem("Normal Item", 0, 0), "Normal Item", -1, 0),
Arguments.of(new NormalItem("Normal Item", 0, 10), "Normal Item", -1, 8));
}
@ParameterizedTest
@MethodSource("provideInputWhereSellInDayPassesByOneDay")
void shouldDegradeQualityForAnItem(NormalItem normalItem, String expectedName, int expectedSellIn, int expectedQuality) {
normalItem.updateQuality();
assertEquals(expectedName, normalItem.name);
assertEquals(expectedSellIn, normalItem.sellIn);
assertEquals(expectedQuality, normalItem.quality);
}
}

View File

@ -0,0 +1,36 @@
package com.gildedrose.model;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertEquals;
class SulfurasTest {
private static Stream<Arguments> provideInputWhereSellInDayPassesByOneDay() {
return Stream.of(
//4."Sulfuras, Hand of Ragnaros"
//4.a before sellIn
Arguments.of(new Sulfuras(10, 80), "Sulfuras, Hand of Ragnaros", 10, 80),
//4.b after sellIn
Arguments.of(new Sulfuras(0, 80), "Sulfuras, Hand of Ragnaros", 0, 80),
Arguments.of(new Sulfuras(-1, 80), "Sulfuras, Hand of Ragnaros", -1, 80));
}
@ParameterizedTest
@MethodSource("provideInputWhereSellInDayPassesByOneDay")
void shouldDegradeQualityForAnItem(Sulfuras sulfuras, String expectedName, int expectedSellIn, int expectedQuality) {
sulfuras.updateQuality();
assertEquals(expectedName, sulfuras.name);
assertEquals(expectedSellIn, sulfuras.sellIn);
assertEquals(expectedQuality, sulfuras.quality);
}
}