// WARNING: DO NOT modify the Item class - the goblin in the corner will insta-rage! class Item { String name; int sellIn; int quality; Item(this.name, this.sellIn, this.quality); @override String toString() => '$name, $sellIn, $quality'; } /// Strategy pattern: Each item type has its own update behavior abstract class ItemUpdater { void update(Item item); } class NormalItemUpdater implements ItemUpdater { @override void update(Item item) { // Quality decreases by 1 each day if (item.quality > 0) { item.quality -= 1; } item.sellIn -= 1; // After sell-by date, quality degrades twice as fast if (item.sellIn < 0 && item.quality > 0) { item.quality -= 1; } } } class AgedBrieUpdater implements ItemUpdater { @override void update(Item item) { // Quality increases as it ages if (item.quality < 50) { item.quality += 1; } item.sellIn -= 1; // After sell-by date, quality increases twice as fast if (item.sellIn < 0 && item.quality < 50) { item.quality += 1; } } } class BackstagePassUpdater implements ItemUpdater { @override void update(Item item) { // Quality increases as concert approaches if (item.quality < 50) { item.quality += 1; // 10 days or less: +2 quality/day if (item.sellIn < 11 && item.quality < 50) { item.quality += 1; } // 5 days or less: +3 quality/day if (item.sellIn < 6 && item.quality < 50) { item.quality += 1; } } item.sellIn -= 1; // After concert, quality drops to 0 if (item.sellIn < 0) { item.quality = 0; } } } class SulfurasUpdater implements ItemUpdater { @override void update(Item item) { // Legendary item never changes // Quality always 80, sellIn never decreases } } class GildedRose { List items; GildedRose(this.items); void updateQuality() { for (final item in items) { final updater = _selectUpdater(item); updater.update(item); } } ItemUpdater _selectUpdater(Item item) { if (item.name == 'Sulfuras, Hand of Ragnaros') { return SulfurasUpdater(); } else if (item.name == 'Aged Brie') { return AgedBrieUpdater(); } else if (item.name == 'Backstage passes to a TAFKAL80ETC concert') { return BackstagePassUpdater(); } else { return NormalItemUpdater(); } } }