Design Patterns - Strategy

Strategy(策略) — 对象行为型模式

定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而改变。

适用场景

  1. 许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。
  2. 需要使用一个算法的不同变体。
  3. 算法使用客户不应该知道的数据。可使用策略模式以避免暴露复杂的,与算法相关的数据结构。
  4. 一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的 Strategy 类中以替代这些条件语句。

UML 图

在这里插入图片描述

效果

  1. 相关算法系列: Strategy 类层次为 Context 定义了一系列的可供复用的算法或行为。继承有助于析取出这些算法中的公共功能。
  2. 客户必须了解不同的 Strategy: 本模式有一个潜在的缺点,就是一个客户要选择一个合适的 Strategy 就必须知道这些 Strategy 到底有何不同。此时可能不得不向客户暴露集体的实现问题。因此仅当这些不同行为的变体与客户相关时,才需要使用 Strategy 模式。

实现

实现有以下一些问题:

  1. 定义 Strategy 和 Context 接口:Strategy 和 Context 接口必须使得 ConcreteStrategy 能够有效地访问它所需要的 Context 中任何数据,反之亦然。一种办法是让 Context 将数据放在参数中传递给 Strategy,这使得 Strategy 和 Context 解耦。但另一方面,Context 可能发送一些 Strategy 不需要的数据。另一种办法就是让 Context 将自身作为一个参数传递给 Strategy,这样 Context 必须对它的数据定义一个更为精细的接口,并且 Strategy 和 Context 更紧密地耦合在一起。
import abc
 
class Student(object):
 
    __metaclass__ = abc.ABCMeta
 
    def __init__(self, *args, **kwargs):
        self.name = args[0]
        self.hobby = args[1]
        self.hometown = args[2]
 
    @abc.abstractmethod
    def introduce(self):
        pass
 
 
class A_cs(Student):
 
    def __init__(self, *args, **kwargs):
        super(A_cs, self).__init__(*args, **kwargs) # 复用父类方法。super(类名,self).方法名
 
    def introduce(self):
        print("I am %s, I like %s, and i like money very much. in the future, "
              "we can make money together, by the way, I come from %s" % (self.name, self.hobby, self.hometown))
 
 
class B_se(Student):
    def __init__(self, *args, **kwargs):
        super(B_se, self).__init__(*args, **kwargs)
 
    def introduce(self):
        print("I am %s, I like %s and so on,I'm from %s,  it is a beautiful place"
              % (self.name, self.hobby, self.hometown))
 
 
class Instructor(object):
    def __init__(self):
        pass
 
    def introduce(self, student):
        return student.introduce()
 
 

client

if __name__ == '__main__':
    xiaoming = A_cs('xiaoming', 'pretty girl', 'zhengzhou')
    xiaogang = B_se('xiaogang', 'money and pretty girl', 'suzhou')
    instructor = Instructor()
    instructor.introduce(xiaoming)
    instructor.introduce(xiaogang)
"""
output:
I am xiaoming, I like pretty girl, and i like money very much. in the future, we can make money together, by the way, I come from zhengzhou
I am xiaogang, I like money and pretty girl and so on,I'm from suzhou,  it is a beautiful place
"""
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值