zoukankan      html  css  js  c++  java
  • 设计模式入门(二):策略模式和桥接模式

    为什么又是两个模式放在一起呢?因为这两个模式也是非常非常的像,但是他们却分属不同的分类,策略模式属于行为型模式,而桥接模式则属于结构型模式。

    首先看两幅UML图

    空心三角连线表示继承关系,空心菱形连线表示组合关系(其中有并使用,是其一部分)。可以看到当用面向对象UML表述时,他俩的结构是十分相似的。

    但仍然能看到区别,但是这个区别是由内在的区别而反应出来的,并非是其本质的区别。

    策略模式的关注点主要在于提取算法的抽象,实现不同算法间的替换。

    而桥接模式的关注点在于实体和实现的分离,也就是可以相互独立的变化(策略模式的进化版?)。

    首先来个传统版本的策略模式(面向对象)。

    以这样一个例子。不同的用户有不同的用户积分,然后根据不同的积分可以获取不同的优惠价格,但是根据积分计算优惠价格的算法是会变化的,例如在傻傻节日的时候和一般情况。

    from collections import namedtuple
    import abc
    
    ShoppingItem = namedtuple('ShoppingItem', 'commodity quantity')
    Commodity = namedtuple('Commodity', 'name price')
    User = namedtuple('User', 'name scores')
    
    
    class ShoppingCar:
        def __init__(self, *goods):
            self._goods = list(goods)
    
        def add_goods(self, goods):
            self._goods.append(goods)
    
        def total_price(self):
            return sum(g.price for g in self._goods)
    
    
    class Discount(abc.ABC):
        @abc.abstractmethod
        def price(self, scores, price):
            pass
    
    
    class DefaultDiscount(Discount):
        def price(self, scores, price):
            discount = 0.85 if scores > 1000 else 1
            return discount * price
    
    
    class On1111Discount(Discount):
        def price(self, scores, price):
            discount = 0.8 if scores > 500 else 0.9
            return discount * price
    
    
    class Order:
        def __init__(self, user, car, discount):
            self._user = user
            self._car = car
            self._discount = discount
    
        def price(self):
            return self._car.total_price()
    
        def dicount_price(self):
            return self._discount.price(self._user.scores, self.price())
    
    

    忽略命名元组的影响,这样写是因为懒得写类了(就将其当作类吧)

    然后对于py这种以函数为一等对象的语言,实际策略模式可以简化为如下格式(充分利用语言特性)

    from collections import namedtuple
    import abc
    
    ShoppingItem = namedtuple('ShoppingItem', 'commodity quantity')
    Commodity = namedtuple('Commodity', 'name price')
    User = namedtuple('User', 'name scores')
    
    
    class ShoppingCar:
        def __init__(self, *goods):
            self._goods = list(goods)
    
        def add_goods(self, goods):
            self._goods.append(goods)
    
        def total_price(self):
            return sum(g.price for g in self._goods)
    
    
    def default_discount(scores, price):
        discount = 0.85 if scores > 1000 else 1
        return discount * price
    
    
    def on_1111_discount(scores, price):
        discount = 0.8 if scores > 500 else 0.9
        return discount * price
    
    
    class Order:
        def __init__(self, user, car, discount):
            self._user = user
            self._car = car
            self._discount = discount
    
        def price(self):
            return self._car.total_price()
    
        def dicount_price(self):
            return self._discount(self._user.scores, self.price())
    
    

    也就是直接将 Discount 策略简化为一个函数

    然后是桥接模式,然后会发现我在之前的 设计模式入门(一):外观模式和适配器模式已经写过了,也就是那么绘图的例子。

    所以这里不再给出代码示例,而是给出UML。

  • 相关阅读:
    在SQLite中使用索引优化查询速度
    SQLite支持的SQL数据操作
    left (outer) join , right (outer) join, full (outer) join, (inner) join, cross join 区别
    深入理解Android内存管理原理(六)
    Merge Sorted Array
    Sort Colors
    Construct Binary Tree from Preorder and Inorder Traversal
    Binary Tree Postorder Traversal
    Symmetric Tree
    Rotate Image
  • 原文地址:https://www.cnblogs.com/freesfu/p/15656562.html
Copyright © 2011-2022 走看看