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

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

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

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

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

1、策略模式概述

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

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

假如一個網(wǎng)店制定了下述折扣規(guī)則。

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

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

UML類圖如下:

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

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

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

2、傳統(tǒng)方法實現(xiàn)策略模式:

from abc import ABC, abstractmethodfrom collections import namedtupleCustomer = namedtuple(’Customer’, ’name fidelity’)class LineItem: '''訂單中單個商品的數(shù)量和單價''' 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、使用函數(shù)實現(xiàn)策略模式

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

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))

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

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

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

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

標簽: Python 編程
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产精品17p| 精品亚洲免a| 一区二区精品| 国产精品亚洲一区二区在线观看| 日本精品黄色| 日韩高清中文字幕一区二区| a天堂资源在线| 99国产精品一区二区| 成人影视亚洲图片在线| 日韩成人精品一区二区三区| 午夜国产一区二区| 美女在线视频一区| 国产aa精品| 好看不卡的中文字幕| 久久影院一区| 久久香蕉国产| 亚洲一区久久| 日韩高清一区| 久久精品国产在热久久| 久久av免费| 亚洲伦乱视频| 麻豆精品国产91久久久久久| 国产+成+人+亚洲欧洲在线| 日本不卡免费高清视频在线| 国产99精品一区| 一本综合精品| 美女精品一区二区| 午夜精品成人av| 香蕉久久久久久久av网站| 日韩高清二区| 日韩精品不卡一区二区| 日韩视频免费| 久久国产精品免费一区二区三区| 国产成人精品一区二区免费看京 | 国产亚洲高清视频| 亚洲精品人人| 久久精品伊人| 蜜臀国产一区| 免费观看久久久4p| 欧美性www| а√在线中文在线新版| 国产农村妇女精品一二区| 日韩免费精品| 国产成人a视频高清在线观看| 亚洲精品888| 日韩国产高清在线| 久久久国产亚洲精品| 亚洲精选久久| 高清日韩欧美| 丝袜亚洲另类欧美| 国产精品sss在线观看av| 国产二区精品| 日韩午夜视频在线| 欧美二三四区| 国产日韩欧美一区二区三区在线观看| 欧美日韩精品免费观看视欧美高清免费大片 | 日韩亚洲在线| 久久不卡日韩美女| 一区福利视频| 美女精品一区二区| 亚洲欧美日本日韩| 亚洲国产欧美日本视频| 亚洲精品四区| 婷婷成人综合| 免费看一区二区三区| 亚洲欧美日韩国产综合精品二区| 精品一区二区三区四区五区| 女人天堂亚洲aⅴ在线观看| 久久精品国产免费| 美女国产精品| 久久高清免费| 九九九精品视频| 天堂精品久久久久| 国产九九精品| 亚洲我射av| 成人午夜网址| 亚洲一区二区日韩| 久久精品色播| 欧美日本精品| 久久亚洲风情| 久久不见久久见中文字幕免费| 久久精品亚洲人成影院| 欧美99久久| 久久99影视| 亚洲天堂日韩在线| 国产精品高潮呻吟久久久久| 国产精品sm| 久久尤物视频| 日韩一区二区三区在线看| 深夜福利视频一区二区| 国产在线欧美| 久色成人在线| 欧美亚洲精品在线| 91一区二区| 国产乱人伦丫前精品视频| 视频一区视频二区中文| 欧美sss在线视频| 精品亚洲二区| 日韩欧美二区| 日韩视频一二区| 美女精品在线| 视频二区不卡| 九一国产精品| 日韩精品电影| 亚洲精品护士| 九九综合九九| 国产毛片精品久久| 亚洲一区欧美激情| 不卡在线一区二区| 极品日韩av| 久久天堂av| 日本少妇一区| 日韩成人亚洲| 日韩免费福利视频| 国产美女高潮在线| 黑森林国产精品av| caoporn视频在线| 欧美一区久久久| 午夜精品久久久久久久久久蜜桃| 精品日产乱码久久久久久仙踪林| 蜜臀av亚洲一区中文字幕| 日韩不卡免费高清视频| 免费成人性网站| 偷拍欧美精品| 午夜精品成人av| 午夜在线一区| 亚洲另类视频| 亚洲三级网站| 视频国产精品| 69堂精品视频在线播放| 欧美日韩精品在线一区| 国产精品黑丝在线播放| 国产一区二区三区精品在线观看 | 国产精品欧美三级在线观看| 日韩av黄色在线| 国产精品一区免费在线| 国产日韩免费| 国产一区二区三区亚洲综合| 中文在线а√天堂| 亚洲人成在线网站| 久久久久国产| 一本色道精品久久一区二区三区| 国产亚洲一区在线| 日韩高清电影一区| 久久精品系列| 欧美中文一区二区| 中文字幕成人| 国产精品亚洲欧美一级在线| 久久影院一区二区三区| 97精品在线| 黄色亚洲精品| 日韩欧美高清一区二区三区| 你懂的国产精品| 99久久亚洲精品蜜臀| 在线免费观看亚洲| 国产精品亚洲产品| 日韩精品91| 香蕉久久国产| 国产精品一区二区三区四区在线观看| 国产成人精品免费视| 欧美日韩国产在线一区| 日韩欧美中文在线观看| 国产成人调教视频在线观看| 亚洲福利国产| 亚洲人www| 国产第一亚洲| 日韩一区欧美二区| 欧美激情麻豆| 国户精品久久久久久久久久久不卡| 亚洲欧美日本国产专区一区| 国产九一精品| 欧美/亚洲一区| 国产三级一区| 99精品小视频| 欧美日韩夜夜| 激情久久久久久| 国产欧美一级| 亚洲激情中文在线| 欧美一区二区三区久久精品| 日韩精品永久网址| 日本中文字幕视频一区| 日韩视频网站在线观看| 婷婷成人av| 91精品啪在线观看国产18| 国产一区二区三区四区五区| 欧美午夜网站| 免费在线亚洲欧美| 精品高清久久| 久久激情婷婷| 久热综合在线亚洲精品| 日日摸夜夜添夜夜添国产精品| 蜜臀va亚洲va欧美va天堂| 不卡一区综合视频| 婷婷综合五月| 日本免费新一区视频| 日韩av中文字幕一区| 麻豆91精品视频| 久久久久久夜| 午夜欧美精品| 亚洲3区在线|