《重构》——Python代码版本_Chpt1.8-1.9(第一章完结)

 原文是JS代码写的,我试图用Python改写,第一章上半部分的内容可以参考:

重构——Python代码版本_Chpt1-1.6

第一章下半部分的内容包括了很多多态重构的内容,因此单独拉出来一个帖子。

JS的代码和Python的实现形式在很多处还是有一些不同,在阅读的时候不要过于关注代码的形式,要尝试去解读背后的内容。

我会在代码中加入一部分注释用于解释其意图,我觉得已经很清晰了。如果以后有多余的时间,我还会加入流程图来对程序进行说明。

import math

# 定义数据源的结构
class play(object):
    def __init__(self, name_, type_):
        self.name = name_
        self.type = type_


class plays_class(object):
    def __init__(self):
        self.hamlet = play('Hamlet', 'tragedy')
        self.as_like = play('As You Like It', 'comedy')
        self.othello = play('Othello', 'tragedy')


class performance(object):
    def __init__(self, playID, audience):
        self.playID = playID
        self.audience = audience


class invoices_class(object):
    def __init__(self):
        self.customer = 'BigCo'
        self.performances = [
            performance('hamlet', 55),
            performance('as_like', 35),
            performance('othello', 40)
        ]


# 格式转换
def usd(num):
    return '$%.2f' % num


# 文本生成器,通过接收createstatementdata()返回的数据来生成文本
def renderplaintext(data):
    result = f'Statement for {data.customer}\n'

    for perf in data.performances:
        result += f'    {perf.play.name}: {usd(perf.amount / 100)} ({perf.audience} seats) \n'

    result += f'Amount owned is {usd(data.totalamount / 100)} \n'
    result += f'You earned {data.totalvolumecredits} credits\n'
    return result


# 数据生成器,用于计算需要输出的数据
def createstatementdata(invoice, plays):
    class result(object):
        pass

    result.customer = invoice.customer
    result.performances = list(map(enrichPerformance, invoice.performances))
    result.totalamount = totalamount(result)
    result.totalvolumecredits = totalvolumecredits(result)
    return renderplaintext(result)


def enrichPerformance(aPerformance):
    calculator = createPerformanceCalculator(aPerformance, playfor(aPerformance))
    result = aPerformance
    result.play = calculator.play
    result.amount = calculator.amount
    result.volumeCredits = calculator.volumecredits
    return result


# 以查询取代参数
def playfor(aPerformance):
    return plays.__getattribute__(aPerformance.playID)


def totalamount(data):
    result = 0
    for perf in data.performances:
        thisamount = 0
        result += amountfor(perf)
    return result


def totalvolumecredits(data):
    result = 0
    for perf in data.performances:
        result += volumecreditsfor(perf)
    return result


# 子类分流器,以多态取代条件语句
def createPerformanceCalculator(aPerformance, aPlay):
    switch_dict = dict(
        tragedy=TragedyCalculator(aPerformance, aPlay),
        comedy=ComedyCalculator(aPerformance, aPlay)
    )
    return switch_dict.get(aPlay.type)


# 父类,负责更通用的逻辑部分
class PerformanceCalculator(object):

    def __init__(self, aPerformance, aPlay):
        self.performance = aPerformance
        self.play = aPlay

    @property
    def volumecredits(self):
        return max(self.performance.audience - 30, 0)


class TragedyCalculator(PerformanceCalculator):
    @property
    def amount(self):
        result = 40000
        if self.performance.audience > 30:
            result += 1000 * (self.performance.audience - 30)
        return result
    pass


class ComedyCalculator(PerformanceCalculator):
    @property
    def amount(self):
        result = 30000
        if self.performance.audience > 20:
            result += 10000 + 500 * (self.performance.audience - 20)
        result += 300 * self.performance.audience
        return result

    @property
    def volumecredits(self):
        return super().volumecredits + math.floor(self.performance.audience / 5)
    pass


def amountfor(aPerformance):
    return createPerformanceCalculator(aPerformance, playfor(aPerformance)).amount


# 此部分的条件语句if被多态取代条件语句给分流了,分别放入了父类PerformanceCalculator和子类ComedyCalculator中
# def volumecreditsfor(aPerformance):
#     result = 0
#     result += max(aPerformance.audience - 30, 0)
#     # add extra credit for every ten comedy attendees
#     if 'comedy' == playfor(aPerformance).type:
#         result += math.floor(aPerformance.audience / 5)
#    return result


if __name__ == '__main__':
    plays = plays_class()
    invoices = invoices_class()
    print(createstatementdata(invoices, plays))

  “互联网精神”即:开放、平等、协作、快速、分享

对更多内容感兴趣欢迎关注我的个人公众号:梧承 Book House

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值