日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

詳解Python設計模式之策略模式

瀏覽:165日期:2022-07-21 10:46:38

雖然設計模式與語言無關,但這并不意味著每一個模式都能在每一門語言中使用。《設計模式:可復用面向對象軟件的基礎》一書中有 23 個模式,其中有 16 個在動態語言中“不見了,或者簡化了”。

1、策略模式概述

策略模式:定義一系列算法,把它們一一封裝起來,并且使它們之間可以相互替換。此模式讓算法的變化不會影響到使用算法的客戶。

電商領域有個使用“策略”模式的經典案例,即根據客戶的屬性或訂單中的商品計算折扣。

假如一個網店制定了下述折扣規則。

有 1000 或以上積分的顧客,每個訂單享 5% 折扣。 同一訂單中,單個商品的數量達到 20 個或以上,享 10% 折扣。 訂單中的不同商品達到 10 個或以上,享 7% 折扣。

簡單起見,我們假定一個訂單一次只能享用一個折扣。

UML類圖如下:

詳解Python設計模式之策略模式

Promotion 抽象類提供了不同算法的公共接口,fidelityPromo、BulkPromo 和 LargeOrderPromo 三個子類實現具體的“策略”,具體策略由上下文類的客戶選擇。

在這個示例中,實例化訂單(Order 類)之前,系統會以某種方式選擇一種促銷折扣策略,然后把它傳給 Order 構造方法。具體怎么選擇策略,不在這個模式的職責范圍內。(選擇策略可以使用工廠模式。)

2、傳統方法實現策略模式:

from abc import ABC, abstractmethodfrom collections import namedtupleCustomer = 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.quantityclass Order: '''訂單''' def __init__(self, customer, cart, promotion=None): self.customer = customer self.cart = list(cart) self.promotion = promotion 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 = ’<訂單 總價: {:.2f} 實付: {:.2f}>’ return fmt.format(self.total(), self.due())class Promotion(ABC): # 策略:抽象基類 @abstractmethod def discount(self, order): '''返回折扣金額(正值)'''class FidelityPromo(Promotion): # 第一個具體策略 '''為積分為1000或以上的顧客提供5%折扣''' def discount(self, order): return order.total() * 0.05 if order.customer.fidelity >= 1000 else 0class BulkItemPromo(Promotion): # 第二個具體策略 '''單個商品為20個或以上時提供10%折扣''' def discount(self, order): discount = 0 for item in order.cart: if item.quantity >= 20: discount += item.total() * 0.1 return discountclass 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() * 0.07 return 0joe = Customer(’John Doe’, 0)ann = Customer(’Ann Smith’, 1100)cart = [LineItem(’banana’, 4, 0.5), LineItem(’apple’, 10, 1.5), LineItem(’watermellon’, 5, 5.0)]print(’策略一:為積分為1000或以上的顧客提供5%折扣’)print(Order(joe, cart, FidelityPromo()))print(Order(ann, cart, FidelityPromo()))banana_cart = [LineItem(’banana’, 30, 0.5), LineItem(’apple’, 10, 1.5)]print(’策略二:單個商品為20個或以上時提供10%折扣’)print(Order(joe, banana_cart, BulkItemPromo()))long_order = [LineItem(str(item_code), 1, 1.0) for item_code in range(10)]print(’策略三:訂單中的不同商品達到10個或以上時提供7%折扣’)print(Order(joe, long_order, LargeOrderPromo()))print(Order(joe, cart, LargeOrderPromo()))

輸出:

策略一:為積分為1000或以上的顧客提供5%折扣<訂單 總價: 42.00 實付: 42.00><訂單 總價: 42.00 實付: 39.90>策略二:單個商品為20個或以上時提供10%折扣<訂單 總價: 30.00 實付: 28.50>策略三:訂單中的不同商品達到10個或以上時提供7%折扣<訂單 總價: 10.00 實付: 9.30><訂單 總價: 42.00 實付: 42.00>

3、使用函數實現策略模式

在傳統策略模式中,每個具體策略都是一個類,而且都只定義了一個方法,除此之外沒有其他任何實例屬性。它們看起來像是普通的函數一樣。的確如此,在 Python 中,我們可以把具體策略換成了簡單的函數,并且去掉策略的抽象類。

from collections import namedtupleCustomer = 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.quantityclass Order: def __init__(self, customer, cart, promotion=None): self.customer = customer self.cart = list(cart) self.promotion = promotion 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(self) return self.total() - discount def __repr__(self): fmt = ’<訂單 總價: {:.2f} 實付: {:.2f}>’ return fmt.format(self.total(), self.due())def fidelity_promo(order): '''為積分為1000或以上的顧客提供5%折扣''' return order.total() * .05 if order.customer.fidelity >= 1000 else 0def bulk_item_promo(order): '''單個商品為20個或以上時提供10%折扣''' discount = 0 for item in order.cart: if item.quantity >= 20: discount += item.total() * .1 return discountdef large_order_promo(order): '''訂單中的不同商品達到10個或以上時提供7%折扣''' distinct_items = {item.product for item in order.cart} if len(distinct_items) >= 10: return order.total() * .07 return 0joe = Customer(’John Doe’, 0)ann = Customer(’Ann Smith’, 1100)cart = [LineItem(’banana’, 4, 0.5), LineItem(’apple’, 10, 1.5), LineItem(’watermellon’, 5, 5.0)]print(’策略一:為積分為1000或以上的顧客提供5%折扣’)print(Order(joe, cart, fidelity_promo))print(Order(ann, cart, fidelity_promo))banana_cart = [LineItem(’banana’, 30, 0.5), LineItem(’apple’, 10, 1.5)]print(’策略二:單個商品為20個或以上時提供10%折扣’)print(Order(joe, banana_cart, bulk_item_promo))long_order = [LineItem(str(item_code), 1, 1.0) for item_code in range(10)]print(’策略三:訂單中的不同商品達到10個或以上時提供7%折扣’)print(Order(joe, long_order, large_order_promo))print(Order(joe, cart, large_order_promo))

其實只要是支持高階函數的語言,就可以如此實現,例如 C# 中,可以用委托實現。只是如此實現反而使代碼變得復雜不易懂。而 Python 中,函數天然就可以當做參數來傳遞。

值得注意的是,《設計模式:可復用面向對象軟件的基礎》一書的作者指出:“策略對象通常是很好的享元。” 享元是可共享的對象,可以同時在多個上下文中使用。共享是推薦的做法,這樣不必在每個新的上下文(這里是 Order 實例)中使用相同的策略時不斷新建具體策略對象,從而減少消耗。因此,為了避免 [策略模式] 的運行時消耗,可以配合 [享元模式] 一起使用,但這樣,代碼行數和維護成本會不斷攀升。

在復雜的情況下,需要具體策略維護內部狀態時,可能需要把“策略”和“享元”模式結合起來。但是,具體策略一般沒有內部狀態,只是處理上下文中的數據。此時,一定要使用普通的函數,別去編寫只有一個方法的類,再去實現另一個類聲明的單函數接口。函數比用戶定義的類的實例輕量,而且無需使用“享元”模式,因為各個策略函數在 Python 編譯模塊時只會創建一次。普通的函數也是“可共享的對象,可以同時在多個上下文中使用”。

以上就是詳解Python設計模式之策略模式的詳細內容,更多關于Python 策略模式的資料請關注好吧啦網其它相關文章!

標簽: Python 編程
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
粉嫩av一区二区三区四区五区 | 国产在线观看91一区二区三区| 伊人久久婷婷| av一区在线| 日韩激情一区| 日韩精品dvd| 亚洲啊v在线| 久久精品观看| 日韩一区二区久久| 三级欧美在线一区| 日本在线不卡视频| 国产麻豆精品久久| 精品亚洲精品| 亚洲天堂资源| 欧美在线观看视频一区| 欧美日韩国产探花| 爽好久久久欧美精品| 天堂俺去俺来也www久久婷婷| 亚洲三级毛片| 国产欧美日韩免费观看| 精品久久中文| 三上悠亚国产精品一区二区三区 | 日韩在线高清| 欧美aa国产视频| 免费人成在线不卡| 日本视频在线一区| 韩日一区二区| 久久国产电影| 日韩视频一区| 日本免费新一区视频| 久久久久黄色| 久久精品成人| 亚洲精品第一| 久久精品日韩欧美| 欧美特黄一级大片| 亚洲欧美日本国产| 久久精品国产免费| 亚洲福利免费| 天堂精品久久久久| 成午夜精品一区二区三区软件| 欧美日韩一区二区综合| 亚洲一级淫片| 久久中文字幕一区二区| 天堂资源在线亚洲| 婷婷久久免费视频| 国产黄大片在线观看| 亚洲制服少妇| 精品国产一区二区三区av片| 好看的av在线不卡观看| 国产免费av一区二区三区| 日韩久久一区二区三区| 亚洲精品影视| 樱桃视频成人在线观看| 一区二区精品| 国产资源在线观看入口av| 视频精品一区二区| 麻豆一区二区在线| 99在线观看免费视频精品观看| 日韩动漫一区| 亚洲风情在线资源| 日本99精品| 国产99精品| 国产精品视频一区二区三区综合| 99久久精品国产亚洲精品| 欧美一区二区三区久久| 久久要要av| 国产精品综合| 99视频在线精品国自产拍免费观看| 国产探花一区| 亚洲激精日韩激精欧美精品| 欧美黄色一区| 亚洲专区视频| 久久精品亚洲欧美日韩精品中文字幕| 亚洲资源网站| 精品日韩视频| 国产精品对白| 中文字幕免费一区二区| 999精品色在线播放| 国产极品一区| 亚洲精品欧美| 欧美影院三区| 国产福利片在线观看| 午夜精品福利影院| 女人av一区| 国产不卡一区| 国产亚洲一区二区三区不卡| 一区二区高清| 婷婷色综合网| 精品精品国产三级a∨在线| 国产精品美女久久久浪潮软件| 福利一区和二区| 青青在线精品| 免费久久99精品国产| 四虎4545www国产精品| 国产精品欧美大片| 日韩欧美中文在线观看| 99热精品在线| 国产专区一区| 久久久久久婷| 国产日韩视频| 综合一区二区三区| 在线亚洲成人| 久久青草久久| 久久一区亚洲| 日韩精品导航| 国产亚洲综合精品| 久久在线免费| 日韩欧美三级| 欧美黄色一区二区| 国产亚洲精品美女久久久久久久久久| 免费人成黄页网站在线一区二区| 亚洲欧美日韩高清在线| 日韩电影免费网址| 国产不卡精品| 精品久久福利| 久久99高清| 精品久久福利| 精品入口麻豆88视频| 日本免费在线视频不卡一不卡二| 免费视频久久| 蜜桃久久久久久| 喷白浆一区二区| 亚洲美洲欧洲综合国产一区| 久久免费大视频| 亚洲高清久久| 国产在线|日韩| 成人福利av| 婷婷综合六月| 久久亚洲专区| 欧美69视频| 宅男在线一区| 视频一区中文| 精品一区免费| 亚洲一级二级| 久久久9色精品国产一区二区三区| zzzwww在线看片免费| 日本在线高清| 日韩精品dvd| 亚洲伦乱视频| 成人看片网站| 国产综合婷婷| 性色av一区二区怡红| 性色av一区二区怡红| 亚洲免费观看高清完整版在线观| 亚洲精品少妇| 国产图片一区| 久久av免费看| 三上亚洲一区二区| 日韩精品免费一区二区三区| 国产精品久久久久久久免费观看| 国产99在线| 香蕉人人精品| 亚洲我射av| 久久精品99国产精品| 国产伦精品一区二区三区在线播放| 国产亚洲高清在线观看| 久久中文在线| 日本精品影院| 亚洲欧美日韩精品一区二区| 中文字幕一区日韩精品| 国产欧美日韩视频在线| 鲁鲁在线中文| 欧美特黄一级| 日本成人在线不卡视频| 久久激情五月婷婷| 国产不卡av一区二区| 久久精品国产99久久| 免费人成在线不卡| 国产精品22p| 99久久婷婷| 亚洲字幕久久| 激情不卡一区二区三区视频在线| 欧美成人综合| 日韩福利视频一区| 日韩欧美一区二区三区免费看| 亚洲欧美久久久| 国产福利亚洲| 亚洲成人二区| 日本成人一区二区| 国产美女亚洲精品7777| 欧美成a人免费观看久久| 视频一区国产视频| 加勒比视频一区| 黄色成人精品网站| 欧美日韩一区二区国产| 日韩欧美一区二区三区在线观看| 好吊日精品视频| 久久精品99国产精品| 播放一区二区| 日韩av资源网| 久久精品欧美一区| 国产日韩三级| 欧美日韩免费观看一区=区三区 | 国产一区国产二区国产三区| 亚洲神马久久| 美女视频免费精品| 亚洲欧美久久| 国产h片在线观看| 日韩激情啪啪| 久久中文字幕二区|