Kata09:第一個(gè)class

Kata09地址

前幾個(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ī)則。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容