Kata09:第一个class

Kata09地址

前几个Kata基本上是为了练习而练习,猜测作者的目的是锻炼读者抽象和重构的意识。思维训练过后,这个Kata又要结合具体场景进行实战了。

还记得第一个Kata吗?在第一个Kata中我们不需要写代码,只是通过思考提出了一个定价模型,而这个Kata的要求正是实现Kata01中的部分策略。

假设有如下定价策略:

  商品   单价      特价
  --------------------------
    A     50       3 个 130
    B     30       2 个 45
    C     20
    D     15

需要实现收款机模型,读入购买物品,输出总价。

思路

乍一看挺简单的,不断读入商品,如果发现有商品满足特价条件就应用特价,最终结算总价。不过有几个细节需要思考。

如何抽象特价规则

题目中的特价规则很简单,每条规则只涉及一件商品,那如果涉及多个商品如何处理?

如何应用特价

应用特价时对特价商品进行标记还是直接把特价商品和普通商品存储在不同类别中?

如何计算总价

每次读入商品处理完之后更新总价?还是动态计算价格?

我的选择请看代码。

代码

class PriceCalculator:

    def __init__(self, prices, rules):
        self.prices = prices
        self.rules = rules
        self.special = {}    # 特价商品和普通商品分开存储
        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):    # 动态计算价格
        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},    # 规则可以包含不同数量的不同商品
    1: {'good': {'B': 2}, 'price': 45}
}

cal = PriceCalculator(prices, rules)
cal.add('AAAAAA')
print cal.getPrice()

上面的三个问题都在注释中标出了我的解决方案,具体的细节请阅读代码。

可以通过add方法多次输入商品,我这里只读入了一次,其实是支持多次的。

总结

我的模型有点过于简单,如果把商品抽象为另一个class应该会更合适一些,不过总体的逻辑并没有区别。

特价规则现在可以满足满减的情况,但是并不能满足买赠,可以进一步把规则抽象成两部分:条件和优惠,从而满足多种规则。

你可能感兴趣的:(Kata09:第一个class)