美文网首页
策略模式

策略模式

作者: TheTempest | 来源:发表于2019-02-09 17:12 被阅读0次

    1.定义

    策略模式:定义了算法簇[cù],分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。

    2.背景

    (本来是打算用自己业务中的某个场景来进行讲解的,很遗憾之前并没有使用过该模式,之后会尝试使用)

    Joe上班的公司做了一套相当成功的模拟鸭子游戏;SimUDuck。游戏中会出现各种鸭子,一边游泳戏水,一边呱呱叫。此系统的内部设计使用了标准的OO技术,设计了一个鸭子的超类(Superclass),并让各种鸭子继承此超类。但是为了提高竞争力,主管们确定,此模拟程序需要会飞的鸭子来将竞争者抛在后面。

    3.方案

    1.Joe首先想到的方法是在Duck类中加上fly()方法,然后所有鸭子都会继承fly()。但是这个会出现所有的鸭子都有了飞的功能(包括“橡皮鸭子”),他体会到了一件事:当涉及“维护”时,为了“复用”目的而使用继承,结局并不完美。

    2.Joe之后想到的是,继续采用在Duck中添加fly()方法,可以把橡皮鸭中的fly()方法覆盖掉,可是以后我们加入诱饵鸭,又会如何?诱饵鸭是木头假鸭,不会飞也不会叫。显然这并不是一个好的解决方案,每当有新的鸭子子类出现,他就要被迫检查并可能需要覆盖fly()。

    现在我们知道使用继承并不能很好地解决问题,因为鸭子的行为在子类里不断地改变,并且让所有的子类都有这些行为是不恰当的。Flyable接口似乎是个不错的方法,但是Java接口不具有实现代码,所以继承接口无法达到代码的复用。幸运的是,有一个原则,恰好适用此状况。

    设计原则:找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。

    我们知道Duck类内的fly() 和quack() 呱呱叫 会随着鸭子的不同而改变,为了要把这个两个行为从Duck类中分开,我们将它们从Duck类中取出来,建立一组新类型来代表每个行为。我们希望一切能有弹性。毕竟,正是因为一开始鸭子行为没有弹性,才让我们走上现在这条路。我们还想能够“指定”行为到鸭子的实例。比方说,我们想要产生一个新的绿头鸭实例,并指定特定“类型”的飞行行为给它。干脆顺便让鸭子的行为可以动态地改变好了。换句话说,我们应该在鸭子类中包含设定行为的方法,这样就可以在“运行时动态地改变绿头鸭的飞行行为。

    设计原则:针对接口编程(“针对接口编程”真正的意思是“针对超类型supertype编程”),而不是针对实现编程。

    这样鸭子就有一个飞行为,有一个呱呱叫行为。有一个关系相当有趣:每一鸭子都有一个FlyBehavior和一个QuackBehavior,好将飞行和呱呱叫委托给它们代为处理。

    3.最后的设计方案为,我们在Duck类中,创建接口FlyBehavior和QuackBehavior的实例,进行操作,将飞行和呱呱叫委托给上面的两个接口处理。

    当你将两个或多个类结合起来使用,如同比例一般,这就是组合。这种做法和“继承”不同的地方在于,鸭子的行为不是继承来的,而是和适当的行为对象组合来的。

    设计原则:多用组合,少用继承。

    这第三种方案就是应用策略模式,定义了算法簇,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

    相关文章

      网友评论

          本文标题:策略模式

          本文链接:https://www.haomeiwen.com/subject/hklisqtx.html