前幾個(gè)Kata基本上是為了練習(xí)而練習(xí),猜測(cè)作者的目的是鍛煉讀者抽象和重構(gòu)的意識(shí)。思維訓(xùn)練過(guò)后,這個(gè)Kata又要結(jié)合具體場(chǎng)景進(jìn)行實(shí)戰(zhàn)了。
還記得第一個(gè)Kata嗎?在第一個(gè)Kata中我們不需要寫(xiě)代碼,只是通過(guò)思考提出了一個(gè)定價(jià)模型,而這個(gè)Kata的要求正是實(shí)現(xiàn)Kata01中的部分策略。
假設(shè)有如下定價(jià)策略:
商品 單價(jià) 特價(jià)
--------------------------
A 50 3 個(gè) 130
B 30 2 個(gè) 45
C 20
D 15
需要實(shí)現(xiàn)收款機(jī)模型,讀入購(gòu)買(mǎi)物品,輸出總價(jià)。
思路
乍一看挺簡(jiǎn)單的,不斷讀入商品,如果發(fā)現(xiàn)有商品滿(mǎn)足特價(jià)條件就應(yīng)用特價(jià),最終結(jié)算總價(jià)。不過(guò)有幾個(gè)細(xì)節(jié)需要思考。
如何抽象特價(jià)規(guī)則
題目中的特價(jià)規(guī)則很簡(jiǎn)單,每條規(guī)則只涉及一件商品,那如果涉及多個(gè)商品如何處理?
如何應(yīng)用特價(jià)
應(yīng)用特價(jià)時(shí)對(duì)特價(jià)商品進(jìn)行標(biāo)記還是直接把特價(jià)商品和普通商品存儲(chǔ)在不同類(lèi)別中?
如何計(jì)算總價(jià)
每次讀入商品處理完之后更新總價(jià)?還是動(dòng)態(tài)計(jì)算價(jià)格?
我的選擇請(qǐng)看代碼。
代碼
class PriceCalculator:
def __init__(self, prices, rules):
self.prices = prices
self.rules = rules
self.special = {} # 特價(jià)商品和普通商品分開(kāi)存儲(chǔ)
self.normal = {}
def add(self, good):
for i in good:
self.normal.setdefault(i, 0)
self.normal[i] += 1
self.checkRules()
def checkRules(self):
hasChange = True
while hasChange:
hasChange = False
for index, rule in self.rules.iteritems():
satisfied = True
for good in rule['good']:
if not (good in self.normal and self.normal[good] >= rule['good'][good]):
satisfied = False
break
if satisfied:
hasChange = True
self.special.setdefault(index, 0)
self.special[index] += 1
for good in rule['good']:
self.normal[good] -= rule['good'][good]
def getPrice(self): # 動(dòng)態(tài)計(jì)算價(jià)格
totalPrice = 0
for index, count in self.special.iteritems():
totalPrice += self.rules[index]['price'] * count
for good, count in self.normal.iteritems():
totalPrice += self.prices[good] * count
return totalPrice
prices = {'A': 50, 'B': 30, 'C': 20, 'D': 15}
rules = {
0: {'good': {'A': 3}, 'price': 130}, # 規(guī)則可以包含不同數(shù)量的不同商品
1: {'good': {'B': 2}, 'price': 45}
}
cal = PriceCalculator(prices, rules)
cal.add('AAAAAA')
print cal.getPrice()
上面的三個(gè)問(wèn)題都在注釋中標(biāo)出了我的解決方案,具體的細(xì)節(jié)請(qǐng)閱讀代碼。
可以通過(guò)add方法多次輸入商品,我這里只讀入了一次,其實(shí)是支持多次的。
總結(jié)
我的模型有點(diǎn)過(guò)于簡(jiǎn)單,如果把商品抽象為另一個(gè)class應(yīng)該會(huì)更合適一些,不過(guò)總體的邏輯并沒(méi)有區(qū)別。
特價(jià)規(guī)則現(xiàn)在可以滿(mǎn)足滿(mǎn)減的情況,但是并不能滿(mǎn)足買(mǎi)贈(zèng),可以進(jìn)一步把規(guī)則抽象成兩部分:條件和優(yōu)惠,從而滿(mǎn)足多種規(guī)則。