策略模式-strategy pattern

1.首先明白什么是设计模式:
Design Pattern is a solution to a problem in a context.
2.其次,为什么学习设计模式
我觉得如果我们在工作中并没有使用过任何设计模式,只能说明两点:
1).你是一个大神,模式都已在脑中,不需要刻意的去套用某种模式
2). 就是你写的code都太简单了,都只能称之为脚本,简单的脚本。(?我目前就处于这个阶段…)
最近在学习head_first_design_pattern(深入浅出设计模式),故想要记录一下,因为有很多东西,当时学的时候很理解,但是过一段时间就会忘记,所以想要记录一下,方便日后回放…但是想设计模式这样高阶的东西其实不是说你看一本书就能学会的,而是需要日积月累的经验,说白了就是你的代码量上去了,有很多模式都自然而然的出来了,但是我作为一个初学者,还是想要一开始先有个系统的概念,然后再在平时的工作中发现和应用。
  • 什么是策略模式:
策略模式,就是能够把一系列“可互换的”算法封装起来,并根据用户需求来选择其中一种。我们可以通过这种模式将一个父类中会变化的部分提取并封装起来,以便此后可以轻易地改变或者扩展这部分,而不影响其他部分。

看一个例子就可以很清楚这种设计模式了:
我们以《深入浅出设计模式》一书中的例子为例来说明:

即模拟一款游戏,里面有各种各样的鸭子,这里我们只设计两种,一种是会飞的鸭子,另一种是会叫的鸭子。

在策略模式中,有几种不同的行为就定义几个不同的接口,这里我们把会飞、不会飞、会用羽毛飞等统一称为一种行为,即飞行行为;把会呱呱叫、会哇哇叫等统一称为另一种行为,即会叫的行为。

首先,定义第一种行为接口,飞行行为接口,飞行行为下的不同种类都实现这个接口,以表示不同的飞行行为:

class FlyBehavior(object):
    """所有飞行行为都必须实现该类的fly方法"""

    def fly(self):
        raise NotImplementedError()

class FlyDuckWithWings(FlyBehavior):
    """会用羽毛飞的鸭子继承飞行行为类,实现飞行接口"""

    def fly(self):
        print("老子有羽毛,老子会飞,你们会么。2333333。")


class FlyDuckNoWay(FlyBehavior):
    """不会飞的鸭子,继承飞行行为类,实现飞行接口"""

    def fly(self):
        print("我不会飞,坐在角落里诅咒你们掉下来。")

接着定义鸭叫这个行为接口:

class QuackBehavior(object):
    """呱呱叫的行为接口类"""

    def quack(self):
        raise NotImplementedError()


class DuckQuackGua(QuackBehavior):
    """只会呱呱叫的鸭子"""

    def quack(self):
        print("看见美鸭,我会呱呱叫。呱呱呱......")


class DuckQuackWa(object):
    """只会哇哇叫的鸭子"""

    def quack(self):
        print("看见帅鸭,我会哇哇叫。哇哇哇......")

这两种行为类定义完成,并有行为子类定义完成之后,就要定义鸭子类型了。

class Duck(object):
    """鸭子对象"""

    # 为了简单说明,在这里直接放置两个参数,如果大家想要更好的实现,可以使用set方法进行设置
    def __init__(self, fly_duck, quack_duck):
        self.fly_duck = fly_duck
        self.quack_duck = quack_duck

    def fly(self):
        self.fly_duck.fly()

    def quack(self):
        self.quack_duck.quack()

好了,我们测试一下:

if __name__ == '__main__':
 fly_gua_duck = Duck(FlyDuckWithWings(), DuckQuackGua())  # 创建一个会飞会呱的鸭子
 fly_gua_duck.fly()
 fly_gua_duck.quack()

 no_fly_wa_duck = Duck(FlyDuckNoWay(), DuckQuackWa())  # 创建一个不会飞,只会哇哇叫的鸭子
 no_fly_wa_duck.fly()
 no_fly_wa_duck.quack()
 ```
 在上面,我们测试时,使用了类的实例。我们继续精简一下,使用静态方法。
 ```
 class FlyBehavior(object):
 """所有会飞的行为都必须继承该类,并实现其fly方法"""

 @staticmethod
 def fly():
     raise NotImplementedError()


class FlyDuckWithWings(FlyBehavior):
 """会飞的鸭子继承会飞行为类,实现飞行接口"""

 @staticmethod
 def fly():
     print("老子有羽毛,老子会飞,你们会么。2333333。")


class FlyDuckNoWay(FlyBehavior):
 """不会飞的鸭子,继承飞行行为类,实现飞行接口"""

 @staticmethod
 def fly():
     print("我不会飞,坐在角落里诅咒你们掉下来。")

这样,我们在测试的时候,传入类就可以了,无需实例出一个对象来。

好像这种方式也不是很好,接下来,我们使用函数来实现这种行为。

class Duck(object):
    """鸭子对象"""

    def __init__(self, fly_duck, quack_duck):
        self.fly_duck = fly_duck
        self.quack_duck = quack_duck


def fly_with_wings():
    print("老子有羽毛,老子会飞,你们会么。2333333。")


def fly_no_way():
    print("我不会飞,坐在角落里诅咒你们掉下来。")


def quack_gua():
    print("看见美鸭,我会呱呱叫。呱呱呱......")


def quack_wa():
    print("看见帅鸭,我会哇哇叫。哇哇哇......")


if __name__ == '__main__':
    fly_gua_duck = Duck(fly_with_wings(), quack_gua())  # 创建一个会飞会呱的鸭子
    fly_gua_duck.fly
    fly_gua_duck.quack

    no_fly_wa_duck = Duck(fly_no_way(), quack_wa())
    no_fly_wa_duck.fly
    no_fly_wa_duck.quack

哈哈,这样是不是精简了很多,但是在测试的时候,我们传入了函数实例,继续精简。

class Duck(object):
    """鸭子对象"""

    def __init__(self, fly_duck, quack_duck):
        self.fly_duck = fly_duck
        self.quack_duck = quack_duck


def fly_with_wings():
    print("老子有羽毛,老子会飞,你们会么。2333333。")


def fly_no_way():
    print("我不会飞,坐在角落里诅咒你们掉下来。")


def quack_gua():
    print("看见美鸭,我会呱呱叫。呱呱呱......")


def quack_wa():
    print("看见帅鸭,我会哇哇叫。哇哇哇......")


if __name__ == '__main__':
    fly_gua_duck = Duck(fly_with_wings, quack_gua)  # 创建一个会飞会呱的鸭子
    fly_gua_duck.fly_duck()
    fly_gua_duck.quack_duck()

    no_fly_wa_duck = Duck(fly_no_way, quack_wa)
    no_fly_wa_duck.fly_duck()
    no_fly_wa_duck.quack_duck()

嗯,最后一种,我们传入函数对象,直接使用函数对象的callable属性就可以了。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值