tdd-katas/lib/gilded_rose.dart

136 lines
3.1 KiB
Dart

// 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';
}
/// Quality bounds - domain constraints
const int _minQuality = 0;
const int _maxQuality = 50;
const int _legendaryQuality = 80; // unused, just for documentation
/// Helper methods for quality management
void _degradeQuality(Item item, int amount) {
item.quality = (item.quality - amount).clamp(_minQuality, _maxQuality);
}
void _improveQuality(Item item, int amount) {
item.quality = (item.quality + amount).clamp(_minQuality, _maxQuality);
}
/// 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
_degradeQuality(item, 1);
item.sellIn -= 1;
// After sell-by date, quality degrades twice as fast
if (item.sellIn < 0) {
_degradeQuality(item, 1);
}
}
}
class AgedBrieUpdater implements ItemUpdater {
@override
void update(Item item) {
// Quality increases as it ages
_improveQuality(item, 1);
item.sellIn -= 1;
// After sell-by date, quality increases twice as fast
if (item.sellIn < 0) {
_improveQuality(item, 1);
}
}
}
class BackstagePassUpdater implements ItemUpdater {
@override
void update(Item item) {
// Base quality increase
_improveQuality(item, 1);
// 10 days or less: +1 additional
if (item.sellIn <= 10) {
_improveQuality(item, 1);
}
// 5 days or less: +1 additional (total +3/day)
if (item.sellIn <= 5) {
_improveQuality(item, 1);
}
item.sellIn -= 1;
// After concert, quality drops to 0
if (item.sellIn < 0) {
item.quality = _minQuality;
}
}
}
class SulfurasUpdater implements ItemUpdater {
@override
void update(Item item) {
// Legendary item never changes
// Quality always 80, sellIn never decreases
}
}
class ConjuredItemUpdater implements ItemUpdater {
@override
void update(Item item) {
// Conjured items degrade twice as fast as normal items
_degradeQuality(item, 2);
item.sellIn -= 1;
// After sell-by date, quality degrades twice as fast (4x total)
if (item.sellIn < 0) {
_degradeQuality(item, 2);
}
}
}
class GildedRose {
List<Item> 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 if (item.name.startsWith('Conjured')) {
return ConjuredItemUpdater();
} else {
return NormalItemUpdater();
}
}
}