摘要:前言合理使用作為一等對(duì)象的函數(shù),可以使某種設(shè)計(jì)模式得以簡(jiǎn)化。本例中這個(gè)抽象類扮演這個(gè)角色。此外,策略實(shí)例沒有狀態(tài)實(shí)例屬性使用函數(shù)代替抽象類,每個(gè)策略都是函數(shù),不必實(shí)例化,拿來(lái)即用。
前言
合理使用作為一等對(duì)象的函數(shù),可以使某種設(shè)計(jì)模式得以簡(jiǎn)化。關(guān)于策略
定義一系列算法,把它們一一封裝起來(lái),并且使它們可以相互替換。一個(gè)策略模式的示例
規(guī)則
1 有1000或以上積分的客戶,每個(gè)訂單享受5%的折扣。 2 同一個(gè)訂單中,單個(gè)商品的數(shù)量達(dá)到20個(gè)或以上,享受10%折扣。 3 訂單中的不同商品數(shù)達(dá)到10個(gè)或以上,享受7%折扣。
策略模式
上下文
把一些計(jì)算委托給實(shí)現(xiàn)不同算法的可互換組件,它提供服務(wù)。本例中,上下文是Order,它會(huì)根據(jù)不同的算法計(jì)算促銷折扣
策略
實(shí)現(xiàn)不同算法的組件共同的接口。本例中Promotion這個(gè)抽象類扮演這個(gè)角色。
具體策略
策略的具體子類。本例中為 fidelityPromo, BulkPromo, LargeOrderPromo三個(gè)子類。經(jīng)典模式
#!/usr/bin/env python # -*- coding: utf-8 -*- # @File : ex1.py # @Time : 18/10/09 17:01 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, promotion=None): self.customer = customer self.cart = 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 = "函數(shù)模式" return fmt.format(self.total(), self.due()) class Promotion(ABC): # 策略:抽象基類 @abstractmethod def discount(self, order): """ 返回折扣金額(正值) :param order: :return: """ class FidelityPromo(Promotion): # 第一個(gè)具體策略 """ 為積分1000或以上的顧客提供5%折扣 """ def discount(self, order): return order.total() * .05 if order.customer.fidelity >= 1000 else 0 class BulkItemPromo(Promotion): # 第二個(gè)具體策略 """ 單個(gè)商品為20個(gè)或以上時(shí)提供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): # 第三個(gè)具體策略 """ 訂單中的不同商品達(dá)到10個(gè)或以上時(shí)提供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 # 兩個(gè)顧客:joe的積分為0,ann的積分是1100 joe = Customer("John Doe", 0) ann = Customer("Ann Smith", 1100) # 有3個(gè)商品的購(gòu)物車 cart = [LineItem("banana", 4, .5), LineItem("apple", 10, 1.5), LineItem("watermellon", 5, 5.0)] # joe未享受到折扣,ann享受到了5%折扣 ex1 = Order(joe, cart, FidelityPromo()) ex2 = Order(ann, cart, FidelityPromo()) # banana數(shù)量超過20個(gè),joe享受到了10%的折扣 banana_cart = [LineItem("banana", 30, .5), LineItem("apple", 10, 1.5)] ex3 = Order(joe, banana_cart, BulkItemPromo()) # 商品數(shù)量超過了10個(gè),為joe提供了7%的折扣 long_order = [LineItem(str(item_code), 1, 1.0) for item_code in range(10)] ex4 = Order(joe, long_order, LargeOrderPromo()) ex5 = Order(joe, cart, LargeOrderPromo()) print(ex1) print(ex2) print(ex3) print(ex4) print(ex5)
#!/usr/bin/env python # -*- coding: utf-8 -*- # @File : ex2.py # @Time : 18/10/10 10:46 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, promotion=None): self.customer = customer self.cart = 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 = "對(duì)比" return fmt.format(self.total(), self.due()) def fidelity_promo(order): return order.total() * .05 if order.customer.fidelity >= 1000 else 0 def bulk_item_promo(order): discount = 0 for item in order.cart: if item.quantity >= 20: discount += item.total() * .1 return discount def large_order_promo(order): distinct_items = {item.product for item in order.cart} if len(distinct_items) >= 10: return order.total() * .07 return 0 # 兩個(gè)顧客:joe的積分為0,ann的積分是1100 joe = Customer("John Doe", 0) ann = Customer("Ann Smith", 1100) # 有3個(gè)商品的購(gòu)物車 cart = [LineItem("banana", 4, .5), LineItem("apple", 10, 1.5), LineItem("watermellon", 5, 5.0)] eg1 = Order(joe, cart, fidelity_promo) eg2 = Order(ann, cart, fidelity_promo) banana_cart = [LineItem("banana", 30, .5), LineItem("apple", 10, 1.5)] eg3 = Order(joe, banana_cart, bulk_item_promo) long_order = [LineItem(str(item_code), 1, 1.0) for item_code in range(10)] eg4 = Order(joe, long_order, large_order_promo) print(eg1," ", eg2, " ", eg3, " ", eg4)
經(jīng)典模式中每個(gè)具體策略都是一個(gè)類,而且只定義了一個(gè)方法,即discount。此外,策略實(shí)例沒有狀態(tài)(實(shí)例屬性)
使用函數(shù)代替抽象類,每個(gè)策略都是函數(shù),不必實(shí)例化,拿來(lái)即用。新的Order類使用起來(lái)更簡(jiǎn)單,代碼行數(shù)更少。參考
<<流暢的Python>>
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/42605.html
摘要:本篇主要講述中使用函數(shù)來(lái)實(shí)現(xiàn)策略模式和命令模式,最后總結(jié)出這種做法背后的思想。 《流暢的Python》筆記。本篇主要講述Python中使用函數(shù)來(lái)實(shí)現(xiàn)策略模式和命令模式,最后總結(jié)出這種做法背后的思想。 1. 重構(gòu)策略模式 策略模式如果用面向?qū)ο蟮乃枷雭?lái)簡(jiǎn)單解釋的話,其實(shí)就是多態(tài)。父類指向子類,根據(jù)子類對(duì)同一方法的不同重寫,得到不同結(jié)果。 1.1 經(jīng)典的策略模式 下圖是經(jīng)典的策略模式的U...
摘要:做前端開發(fā)已經(jīng)好幾年了,對(duì)設(shè)計(jì)模式一直沒有深入學(xué)習(xí)總結(jié)過。今天第一天,首先來(lái)講策略模式。什么是策略模式四兄弟的經(jīng)典設(shè)計(jì)模式中,對(duì)策略模式的定義如下定義一系列的算法,把它們一個(gè)個(gè)封裝起來(lái),并且使它們可互相替換。 做前端開發(fā)已經(jīng)好幾年了,對(duì)設(shè)計(jì)模式一直沒有深入學(xué)習(xí)總結(jié)過。隨著架構(gòu)相關(guān)的工作越來(lái)越多,越來(lái)越能感覺到設(shè)計(jì)模式成為了我前進(jìn)道路上的一個(gè)阻礙。所以從今天開始深入學(xué)習(xí)和總結(jié)經(jīng)典的設(shè)計(jì)模...
摘要:哪吒社區(qū)技能樹打卡打卡貼函數(shù)式接口簡(jiǎn)介領(lǐng)域優(yōu)質(zhì)創(chuàng)作者哪吒公眾號(hào)作者架構(gòu)師奮斗者掃描主頁(yè)左側(cè)二維碼,加入群聊,一起學(xué)習(xí)一起進(jìn)步歡迎點(diǎn)贊收藏留言前情提要無(wú)意間聽到領(lǐng)導(dǎo)們的談話,現(xiàn)在公司的現(xiàn)狀是碼農(nóng)太多,但能獨(dú)立帶隊(duì)的人太少,簡(jiǎn)而言之,不缺干 ? 哪吒社區(qū)Java技能樹打卡?【打卡貼 day2...
摘要:續(xù)前文后端好書閱讀與推薦,幾十天過去了,又看了兩本好書還有以前看過的書,這里依然把它們總結(jié)歸納一下,加入一些自己的看法有用的鏈接和可能的延伸閱讀,并推薦給需要的同學(xué)。 續(xù)前文 后端好書閱讀與推薦 - Mageek`s Wonderland ,幾十天過去了,又看了兩本好書(還有以前看過的書),這里依然把它們總結(jié)歸納一下,加入一些自己的看法、有用的鏈接和可能的延伸閱讀,并推薦給需要的同學(xué)。...
摘要:續(xù)前文后端好書閱讀與推薦,幾十天過去了,又看了兩本好書還有以前看過的書,這里依然把它們總結(jié)歸納一下,加入一些自己的看法有用的鏈接和可能的延伸閱讀,并推薦給需要的同學(xué)。 續(xù)前文 后端好書閱讀與推薦 - Mageek`s Wonderland ,幾十天過去了,又看了兩本好書(還有以前看過的書),這里依然把它們總結(jié)歸納一下,加入一些自己的看法、有用的鏈接和可能的延伸閱讀,并推薦給需要的同學(xué)。...
閱讀 2861·2021-09-10 10:51
閱讀 2224·2021-09-02 15:21
閱讀 3216·2019-08-30 15:44
閱讀 886·2019-08-29 18:34
閱讀 1663·2019-08-29 13:15
閱讀 3335·2019-08-26 11:37
閱讀 2707·2019-08-26 10:46
閱讀 1118·2019-08-26 10:26