GildedRose-Refactoring-Kata/go/gilded-rose.go
2020-07-17 10:08:23 +07:00

160 lines
2.8 KiB
Go

package main
import "fmt"
type Item struct {
name string
sellIn, quality int
}
var items = []Item{
Item{"+5 Dexterity Vest", 10, 20},
Item{"Aged Brie", 2, 0},
Item{"Elixir of the Mongoose", 5, 7},
Item{"Sulfuras, Hand of Ragnaros", 0, 80},
Item{"Backstage passes to a TAFKAL80ETC concert", 15, 20},
Item{"Conjured Mana Cake", 3, 6},
}
type Updatable interface {
Update()
}
type UpdatableItem func(item *Item) Updatable
type AgedBrieItem struct {
*Item
}
func (item *AgedBrieItem) Update() {
item.updateSellIn(-1)
if item.sellIn < 0 {
item.updateQuality(+2)
} else {
item.updateQuality(+1)
}
item.limitQualityToMax(50)
}
type SulfurasItem struct {
*Item
}
func (item *SulfurasItem) Update() {
}
type BackstagePassesItem struct {
*Item
}
func (item *BackstagePassesItem) Update() {
item.updateSellIn(-1)
sellIn := item.sellIn
switch {
case sellIn >= 10:
item.updateQuality(+1)
case sellIn < 10 && sellIn >= 5:
item.updateQuality(+2)
case sellIn < 15 && sellIn >= 0:
item.updateQuality(+3)
case sellIn < 0:
item.limitQualityToMax(0)
}
item.limitQualityToMax(50)
}
type RegularItem struct {
*Item
}
func (item *RegularItem) Update() {
item.updateSellIn(-1)
if item.sellIn < 0 {
item.updateQuality(-2)
} else {
item.updateQuality(-1)
}
item.limitQualityToMin(0)
}
type ConjuredItem struct {
*Item
}
func (item *ConjuredItem) Update() {
item.updateSellIn(-1)
if item.sellIn < 0 {
item.updateQuality(-4)
} else {
item.updateQuality(-2)
}
item.limitQualityToMin(0)
}
func UpdatableItemFactory(createClosure map[string]UpdatableItem, item *Item) Updatable {
create, exists := createClosure[item.name]
if exists {
return create(item)
}
return &RegularItem{
Item: item,
}
}
func (item *Item) updateSellIn(updatedBy int) {
item.sellIn += updatedBy
}
func (item *Item) updateQuality(updatedBy int) {
item.quality += updatedBy
}
func (item *Item) limitQualityToMax(max int) {
if item.quality > max {
item.quality = max
}
}
func (item *Item) limitQualityToMin(min int) {
if item.quality < min {
item.quality = min
}
}
func GildedRose(items []Item) {
creationMap := map[string]UpdatableItem{
"Aged Brie": func(item *Item) Updatable {
return &AgedBrieItem{
Item: item,
}
},
"Sulfuras, Hand of Ragnaros": func(item *Item) Updatable {
return &SulfurasItem{
Item: item,
}
},
"Backstage passes to a TAFKAL80ETC concert": func(item *Item) Updatable {
return &BackstagePassesItem{
Item: item,
}
},
"Conjured Mana Cake": func(item *Item) Updatable {
return &ConjuredItem{
Item: item,
}
},
}
for i := 0; i < len(items); i++ {
updatableItem := UpdatableItemFactory(creationMap, &items[i])
updatableItem.Update()
}
}
func main() {
fmt.Println("# Before updating")
// fmt.Println(items)
GildedRose(items)
}