原文取自大话设计模式,不同之处在于原文是基于C#编写的,这里用Python表述

需求:使用python语言开发实现一个商场消费打折、优惠活动,保证其可扩展性

初学者代码如下:

# if __name__ == "__main__":
#     print("请输入打折折扣:")
#     a = input()
#     print("请输入总金额:")
#     price = input()
#     if (a == "9折"):
#         print(float(price) * 0.9)
#     elif (a == "8折"):
#         print(float(price) * 0.1)
#     elif (a == "7折"):
#         pass
#     else:
#         pass

缺点不再赘述

简单工厂代码如下:

# 简单工厂模式
# 一个工厂、一个实体类(含抽象方法)、多个抽象方法的实现类
# 经常变动的为打折、不变的为总额、两者有关联关系
# 则总额为实体类、打着为抽象方法的实现类


# 抽象类,参数为商品原价,返回结果为实付价格
# 即将返回结果进行抽象化
class cashSuper():
    # 抽象类,子类必须实现该类
    @abc.abstractmethod
    def acceptCash(self,money):
        pass


# 正常收费类
class cashNormal(cashSuper):
    def acceptCash(self,money):
        return money


# 打折类
class cashRebate(cashSuper):
    # 打折数
    moneyRebat=0
    # init函数等同与构造函数
    def __init__(self, moneyRebate):
        self.moneyRebate = moneyRebate

    def acceptCash(self,money):
        return float(money) * float(self.moneyRebate)


# 满减类
class cashReturn(cashSuper):
    # 满足金额
    moneyCondition = 0
    # 返利
    moneyCondition = 0

    def __init__(self, moneyCondition, moneyReturn):
        self.moneyCondition = moneyCondition
        self.moneyReturn = moneyReturn

    def acceptCash(self,money):
        result = float(self.money)
        if (result >= self.conditionPirce):
            result = money - math.floor(money / self.moneyCondition) * self.moneyReturn
        return result

# 优惠工厂类
class createCashAccept():
    # 运算类的静态方法
    @staticmethod
    def createCash(cashType):
        cash = None
        # 这里可以添加其他运算方法
        if (cashType == "正常收费"):
            cash = cashNormal()
        elif (cashType == "满300减100"):
            cash = cashReturn(300,100)
        elif (cashType == "打8折"):
            cash = cashRebate(0.8)
        else:
            pass
        return cash


if __name__ == "__main__":
    print("请输入消费金额:")
    price = input()
    print("请输入优惠类型:")
    type = input()
    cash = createCashAccept.createCash(type)
    print("总金额:",cash.acceptCash(price))

上面的简单工厂模式使用了静态方法,静态方法属于对参数没有要求,不需要设置(也没办法设置)“self”和“cls”参数。

其方法体中不能使用类或实例的任何属性和方法;

若一个类中包含静态方法,那么该类的实例、或者通过其类名都可以调用该方法。

策略模式主要是通过类的实例对象进行操作。

策略模式和工厂模式结合后代码如下:

# 抽象类,参数为商品原价,返回结果为实付价格
# 即将返回结果进行抽象化
class cashSuper():
    # 抽象类,子类必须实现该类
    @abc.abstractmethod
    def acceptCash(self,money):
        pass


# 正常收费类
class cashNormal(cashSuper):
    def acceptCash(self,money):
        return money


# 打折类
class cashRebate(cashSuper):
    # 打折数
    moneyRebat=0
    # init函数等同与构造函数
    def __init__(self, moneyRebate):
        self.moneyRebate = moneyRebate

    def acceptCash(self,money):
        return float(money) * float(self.moneyRebate)


# 满减类
class cashReturn(cashSuper):
    # 满足金额
    moneyCondition = 0
    # 返利
    moneyCondition = 0

    def __init__(self, moneyCondition, moneyReturn):
        self.moneyCondition = moneyCondition
        self.moneyReturn = moneyReturn

    def acceptCash(self,money):
        result = float(self.money)
        if (result >= self.conditionPirce):
            result = money - math.floor(money / self.moneyCondition) * self.moneyReturn
        return result


# 策略模式和简单工厂模式组合
class CashContext():
    #声明一个现金收费父类对象
    cs=cashSuper()
    #设置策略行为,参数为具体的现金收费子类(正常,打折或返利)
    def __init__(self,type):
        if (type == "正常收费"):
            self.cs = cashNormal()
        elif (type == "满300减100"):
            self.cs = cashReturn(300, 100)
        elif (type == "打8折"):
            self.cs = cashRebate(0.8)
        else:
            pass
    #得到现金促销计算结果(利用了多态机制,不同的策略行为导致不同的结果)
    def GetResult(self,money):
        return self.cs.acceptCash(money)

# 主函数
if __name__ == "__main__":
    print("请输入消费金额:")
    price = input()
    print("请输入优惠类型:")
    type = input()
    cashSuper=CashContext(type)
    print("价格为:",cashSuper.GetResult(price))

策略工厂模式总结:

#一个基类(包含抽象方法),基类的实现类 (扩展类)

# 一个策略类(不包含静态方法、一个可以返回基类的扩展类的方法、一个封装了基类返回结果的方法)、

# 一个主函数

代码敲完了,没发现简单工厂模式、和策略工厂模式有什么特别的差别。

主要区别就是:

简单工厂模式是基于类的静态方法,该静态方法直接返回了【基类】的【扩展类】的【对象】,如若后期对其【扩展类】的【acceptCash方法】有该动,则直接影响到其的调用。

比如上面的简单工厂代码中,当主函数中【有多个】通过【工厂类获取到】的【不同对象】,并且调用了这些【不同对象】的cash.acceptCash()方法,若该方法名称进行了修改,则所有的调用该方法的代码都要修改。

 

而策略工厂模式中,如若上述的【方法名称】进行了修改,只需要修改策略工厂类【CashContext】中【GetResult()方法】中的【基类调用方法】这一处代码即可。

 

对于调用者而言,无论【GetResult()方法】里的内容如何修改,他只需要调用该方法即可,怎么修改都不会影响其已编写的代码逻辑!

以下是所有代码:

# 日期:2019-03-13
# 简介:策略模式
# 人员:Hyl

# 基本代码
import abc
import math


# if __name__ == "__main__":
#     print("请输入打折折扣:")
#     a = input()
#     print("请输入总金额:")
#     price = input()
#     if (a == "9折"):
#         print(float(price) * 0.9)
#     elif (a == "8折"):
#         print(float(price) * 0.1)
#     elif (a == "7折"):
#         pass
#     else:
#         pass


# 简单工厂模式
# 一个工厂、一个实体类(含抽象方法)、多个抽象方法的实现类
# 经常变动的为打折、不变的为总额、两者有关联关系
# 则总额为实体类、打着为抽象方法的实现类


# 抽象类,参数为商品原价,返回结果为实付价格
# 即将返回结果进行抽象化
class cashSuper():
    # 抽象类,子类必须实现该类
    @abc.abstractmethod
    def acceptCash(self,money):
        pass


# 正常收费类
class cashNormal(cashSuper):
    def acceptCash(self,money):
        return money


# 打折类
class cashRebate(cashSuper):
    # 打折数
    moneyRebat=0
    # init函数等同与构造函数
    def __init__(self, moneyRebate):
        self.moneyRebate = moneyRebate

    def acceptCash(self,money):
        return float(money) * float(self.moneyRebate)


# 满减类
class cashReturn(cashSuper):
    # 满足金额
    moneyCondition = 0
    # 返利
    moneyCondition = 0

    def __init__(self, moneyCondition, moneyReturn):
        self.moneyCondition = moneyCondition
        self.moneyReturn = moneyReturn

    def acceptCash(self,money):
        result = float(self.money)
        if (result >= self.conditionPirce):
            result = money - math.floor(money / self.moneyCondition) * self.moneyReturn
        return result

# 优惠工厂类
class createCashAccept():
    # 运算类的静态方法
    @staticmethod
    def createCash(cashType):
        cash = None
        # 这里可以添加其他运算方法
        if (cashType == "正常收费"):
            cash = cashNormal()
        elif (cashType == "满300减100"):
            cash = cashReturn(300,100)
        elif (cashType == "打8折"):
            cash = cashRebate(0.8)
        else:
            pass
        return cash


# #使用工厂方式实现需求
# if __name__ == "__main__":
#     print("请输入消费金额:")
#     price = input()
#     print("请输入优惠类型:")
#     type = input()
#     cash = createCashAccept.createCash(type)
#     print("总金额:",cash.acceptCash(price))


#
# 策略模式和简单工厂模式组合
class CashContext():
    #声明一个现金收费父类对象
    cs=cashSuper()
    #设置策略行为,参数为具体的现金收费子类(正常,打折或返利)
    def __init__(self,type):
        if (type == "正常收费"):
            self.cs = cashNormal()
        elif (type == "满300减100"):
            self.cs = cashReturn(300, 100)
        elif (type == "打8折"):
            self.cs = cashRebate(0.8)
        else:
            pass

    #得到现金促销计算结果(利用了多态机制,不同的策略行为导致不同的结果)
    def GetResult(self,money):
        return self.cs.acceptCash(money)



# # #使用策略模式实现需求
if __name__ == "__main__":
    print("请输入消费金额:")
    price = input()
    print("请输入优惠类型:")
    type = input()
    cashSuper=CashContext(type)
    print("价格为:",cashSuper.GetResult(price))

编码小发现:

python编码常使用实例方法、类方法、静态方法、抽象方法。

实例方法不需要特别声明。

类方法需要使用装饰器@classmethod声明

静态方法需要使用装饰器@staticmethod声明

抽象方法较为特殊,需要使用@abc.abstractmethod声明