欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

python實現策略模式

系統 1955 0

python實現策略模式

?

原文地址

1、策略模式概述

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

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

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

  • 有 1000 或以上積分的顧客,每個訂單享 5% 折扣。

  • 同一訂單中,單個商品的數量達到 20 個或以上,享 10% 折扣。

  • 訂單中的不同商品達到 10 個或以上,享 7% 折扣。

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

UML類圖如下:

python實現策略模式_第1張圖片

?

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

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

?

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

            
              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 
            
            =
            
               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
            
            
               0



            
            
              class
            
             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
            
            
               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() * 0.07
        
            
              return
            
            
               0


joe 
            
            = 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
            
            
               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 
            
            =
            
               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
            
            
               0



            
            
              def
            
            
               bulk_item_promo(order):
    
            
            
              """
            
            
              單個商品為20個或以上時提供10%折扣
            
            
              """
            
            
              
    discount 
            
            =
            
               0
    
            
            
              for
            
             item 
            
              in
            
            
               order.cart:
        
            
            
              if
            
             item.quantity >= 20
            
              :
            discount 
            
            += item.total() * .1
    
            
              return
            
            
               discount



            
            
              def
            
            
               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
            
            
               0


joe 
            
            = 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 編譯模塊時只會創建一次。普通的函數也是“可共享的對象,可以同時在多個上下文中使用”。

?


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦?。。?/p>

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 日日草夜夜操 | 成人片黄网站A片免费 | 亚洲激情一区 | 精品小视频在线 | 视频一区二区三区免费观看 | 国产精品视频网 | 日本一区视频在线播放 | 国产精品久久久久久久久免费 | 久久久久久精 | 欧美成人欧美激情欧美风情 | 日本老妇人乱视频 | 精品国产三级 | 日本理论片好看理论片 | 2022国产91精品久久久久久 | 一区二区三区网站在线免费线观看 | 国产一起色一起爱 | 午夜视频免费国产在线 | 精品国产欧美 | 国产精品久久久久久一级毛片 | 一区二区三区免费在线观看 | 国产美女精品 | 高校处世王 | 小视频你懂得 | 国产无圣光高清一区二区 | 夜夜艹 | 欧美黄视频网站 | 成人a视频 | 豆国产97在线 | 亚洲 | 久久精品一 | 日日做夜夜操 | 91在线视频播放 | 日日视频| 亚洲免费观看在线视频 | www.夜夜骑.com| 精品国产一区探花在线观看 | 国产精品秒播无毒不卡 | 国产99久久精品一区二区永久免费 | 亚洲精品国产成人 | 国产99久久精品一区二区永久免费 | 奇米影视8888狠狠狠狠 | 欧美金妇欧美乱妇视频 |