读书笔记:《流畅的Python》第六章 使用一等函数实现设计模式
2021/11/1 14:41:04
本文主要是介绍读书笔记:《流畅的Python》第六章 使用一等函数实现设计模式,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
一些概念
# 策略模式 # 定义一系列算法,把它们一一封装起来,并且使他们可以相互替换,使得算法 # 可以独立于使用它的客户而变化。 # 模板方法 # 访问者模式 # 重构策略模式 # 代码: # 经典的策略模式.py # 使用函数实现策略模式.py # 享元(flyweight) # 是可共享的对象,可以同时在多个上下文中使用 # 命令模式 : 目的是解耦调用操作的对象(调用者)和提供实现的对象(接收者)
经典的策略模式:电商折扣.py
# 有1000或者以上积分 享受5%折扣 # 同一订单中单个商品数量达到20或者以上,享10%折扣 # 订单中的不同商品达到10个或以上,享7%折扣 # 一个订单只能享受一个折扣 """上下文: 把计算委托给不同的算法可互换组件,本例为Order,它会根据不同的算法计算促销折扣 策略: 实现不同算法的共同接口,本例中Promotion这个抽象类扮演这个角色 具体策略: 策略的具体子类,fidelityPromo、BulkPromo\LargeOrderPromo是这里实现的三个具体策略""" # 实现Order类,支持插入式折扣策略 from abc import ABC,abstractmethod from collections import namedtuple Customer = namedtuple('Customer','name fidelity') # 用命名元组保存客户信息 名字 忠诚度(积分) class LineItem: def __init__(self,product,quantity,price): # 商品\数量\价格 self.product = product self.quantity = quantity self.price = price def total(self): # 计算金额 return self.price * self.quantity class Order: # 上下文/订单 def __init__(self,customer,cart,promition = None): # 客户\购物车\促销折扣 self.customer = customer self.cart = cart self.promotion = promition def total(self): if not hasattr(self,'__total'): self.__total = sum(item.total() for item in self.cart) return self.__total def due(self): # 应付款 if self.promotion is None: discount = 0 # 折扣率 else: discount = self.promotion.discount(self) return self.total() - discount def __repr__(self): fmt = '<Order total:{:.2f} due:{:.2f}>' return fmt.format(self.total(),self.due()) class Promotion: # 策略,抽象基类 @abstractmethod def discount(self,order): '''返回折扣金额(正值)''' class FidelityPromo(Promotion): # 第一个具体策略 '''为积分1000及以上客户提供5%折扣''' def discount(self,order): return order.total() * .05 if order.customer.fidelity >= 1000 else 0 class BuckItemPromo(Promotion): '''单个商品数量20及以上提供10%的折扣''' def discount(self,order): discount = 0 for item in order.cart: if item.quantity >= 20: discount += item.total()* .1 return discount class LargeOrderPromo(Promotion): '''不同商品达到10个或以上提供7%折扣''' def discount(self,order): distinct_items = {item.product for item in order.cart} # 去重 if len(distinct_items) >= 10: return order.total()*.07 return 0 if __name__ == '__main__': joe = Customer('John Doe',0) ann = Customer('Ann Smith',1100) cart = [LineItem('banana',4,.5), LineItem('apple',10,1.5), LineItem('watermellon',5,5.0)] print(Order(joe, cart, FidelityPromo())) print(Order(ann, cart, FidelityPromo())) banana_cart = [LineItem('banana',30,.5), LineItem('apple',10,1.5)] print(Order(joe, banana_cart, BuckItemPromo())) large_order = [LineItem(str(item_code),1,1.0) for item_code in range(10)] print(Order(joe, large_order, LargeOrderPromo())) print(Order(joe, cart, LargeOrderPromo()))
使用函数实现策略模式.py
# 有1000或者以上积分 享受5%折扣 # 同一订单中单个商品数量达到20或者以上,享10%折扣 # 订单中的不同商品达到10个或以上,享7%折扣 # 一个订单只能享受一个折扣 """上下文: 把计算委托给不同的算法可互换组件,本例为Order,它会根据不同的算法计算促销折扣 策略: 实现不同算法的共同接口,本例中Promotion这个抽象类扮演这个角色 具体策略: 策略的具体子类,fidelityPromo、BulkPromo\LargeOrderPromo是这里实现的三个具体策略""" # 实现Order类,支持插入式折扣策略 from abc import ABC,abstractmethod from collections import namedtuple Customer = namedtuple('Customer','name fidelity') # 用命名元组保存客户信息 名字 忠诚度(积分) class LineItem: def __init__(self,product,quantity,price): # 商品\数量\价格 self.product = product self.quantity = quantity self.price = price def total(self): # 计算金额 return self.price * self.quantity class Order: # 上下文/订单 def __init__(self,customer,cart,promition = None): # 客户\购物车\促销折扣 self.customer = customer self.cart = cart self.promotion = promition def total(self): if not hasattr(self,'__total'): self.__total = sum(item.total() for item in self.cart) return self.__total def due(self): # 应付款 if self.promotion is None: discount = 0 # 折扣率 else: discount = self.promotion.discount(self) return self.total() - discount def __repr__(self): fmt = '<Order total:{:.2f} due:{:.2f}>' return fmt.format(self.total(),self.due()) class Promotion: # 策略,抽象基类 @abstractmethod def discount(self,order): '''返回折扣金额(正值)''' class FidelityPromo(Promotion): # 第一个具体策略 '''为积分1000及以上客户提供5%折扣''' def discount(self,order): return order.total() * .05 if order.customer.fidelity >= 1000 else 0 class BuckItemPromo(Promotion): '''单个商品数量20及以上提供10%的折扣''' def discount(self,order): discount = 0 for item in order.cart: if item.quantity >= 20: discount += item.total()* .1 return discount class LargeOrderPromo(Promotion): '''不同商品达到10个或以上提供7%折扣''' def discount(self,order): distinct_items = {item.product for item in order.cart} # 去重 if len(distinct_items) >= 10: return order.total()*.07 return 0 if __name__ == '__main__': joe = Customer('John Doe',0) ann = Customer('Ann Smith',1100) cart = [LineItem('banana',4,.5), LineItem('apple',10,1.5), LineItem('watermellon',5,5.0)] print(Order(joe, cart, FidelityPromo())) print(Order(ann, cart, FidelityPromo())) banana_cart = [LineItem('banana',30,.5), LineItem('apple',10,1.5)] print(Order(joe, banana_cart, BuckItemPromo())) large_order = [LineItem(str(item_code),1,1.0) for item_code in range(10)] print(Order(joe, large_order, LargeOrderPromo())) print(Order(joe, cart, LargeOrderPromo()))
这篇关于读书笔记:《流畅的Python》第六章 使用一等函数实现设计模式的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-24Python编程基础详解
- 2024-11-21Python编程基础教程
- 2024-11-20Python编程基础与实践
- 2024-11-20Python编程基础与高级应用
- 2024-11-19Python 基础编程教程
- 2024-11-19Python基础入门教程
- 2024-11-17在FastAPI项目中添加一个生产级别的数据库——本地环境搭建指南
- 2024-11-16`PyMuPDF4LLM`:提取PDF数据的神器
- 2024-11-16四种数据科学Web界面框架快速对比:Rio、Reflex、Streamlit和Plotly Dash
- 2024-11-14获取参数学习:Python编程入门教程