原文取自大话设计模式,不同之处在于原文是基于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声明