`
足至迹留
  • 浏览: 495904 次
  • 性别: Icon_minigender_1
  • 来自: OnePiece
社区版块
存档分类
最新评论

策略模式(Strategy)

阅读更多
0、总述
设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。

设计模式分为三种类型,共23种。
创建型模式:单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。
结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
行为型模式:模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式、访问者模式。
因为并不是所有模式都十分常用,有些模式我们只要大概了解,需要时再深入了解即可。而有的模式则渗透几乎所有我们常用框架里,比如代理模式,装饰者模式,观察者模式等需要重点理解掌握。
现在我们从策略模式入手。

1. 例子引入--添加新特性慎用继承
我们要做一套模拟鸭子的游戏程序。我们设计了一个鸭子超类Duck,有swim()和quack()特性,具体子类去实现这些方法。现在我们要增加一个fly()的特性,怎么实现?
如果加在父类上,则所有子类自动继承该特性,如果是橡皮鸭,则不应该具备该特性,那就要自己手动重写该方法屏蔽fly的功能。如果再新加子类同样面临这个问题。

当涉及维护时,为了复用(reuse)目的而使用继承,结局并不完美。一般一套系统,维护的成本一定会超过开发的成本,所以维护的情况一定要考虑。

经过上面的分析,我们需要的是一个更清晰的方法,让“某些”(而不是全部)鸭子类型可飞。这时可能会有人想,我们可以把fly()取出来,放进一个Flyable接口,这么一来,只有会飞的鸭子才实现接口。


这个设计真是糟糕,虽然解决了“部分”问题,但这样重复的代码会变很多,因为接口没有实现,不能让实现接口的类复用代码。这能算是从一个恶梦跳到另一个恶梦。
如果能有一种建立软件的方法,让我们需要改变软件时,可以在对既有的代码影响最小的情况下轻易达到花较少时间重做代码该有多好。幸运的是有一个设计原则,正适应这种状况:
封装变化找出应用中可能需要变化之处,把他们独立封装出来,不要和那些不需要变化的代码放在一起。以便以后可以轻易的扩展该部分,而不会影响其他部分。
系统设计的时候我们需要仔细分析需求,哪部分是容易变化的,比如新增或删除特性。这部分就需要设计上有限照顾。记住,并没有一个法则是系统所有地方都需要满足的,只要重要地方满足就可以了。

2. 分开变化和不变化的部分
对于上面的例子我们该如何开始?我们知道Duck类内的fly()和quack()会随着鸭子的不同而改变,为了要把两个行为从Duck类中分开,我们将把他们自Duck类中取出,建立一组新类代表每个行为。
我们还希望一切能有弹性,比如可以动态的改变实例的行为。有了这个需求,我们需要借助第二个设计原则针对接口编程,而不是针对实现编程

我们利用接口代表每个行为,让接口的实现类来实现不同的具体行为。比如上面的例子,FlyBehavior接口代表飞行的特性,然后用FlyWithWings来具体实现飞行方式。Duck类不需要实现FlyBehavior接口, 而是使用接口的行为,不需要绑定具体实现。
以前的做法是通过给父类增加fly()特性,或直接实现接口来指定具体的fly行为。这两种做法都依赖于“实现”。


这里解释下,为什么不把FlyBehavior设计成抽象类,而是接口?
其实“针对接口编程”真正的意思是“针对超类型(supertype)编程”。这里所谓的接口有多个含义,是一个概念也是一种Java的interface构造,关键就是多态。利用多态,程序可以针对超类型编程,执行时会根据实例状态执行到真正的行为,不会绑死在超类型的行为上。“针对超类型编程”可以更明确地说成“变量的声明类型应该是超类型,通常是一个抽象类或一个接口”,如此只要是具体实现此超类型的类所产生的对象,都可以指定给这个变量,这也意味着,生命类时,不用理会以后执行时的真正对象类型。

扩展理解:接口和抽象类的对比:
http://blog.csdn.net/fenglibing/article/details/2745123
http://dev.yesky.com/436/7581936.shtml
抽象类是模板,接口是规范。

基于上面的分析,为了给Duck新增飞行和鸣叫的行为,我们新增两个接口FlyBehavior和QuackBehavior,还有它们对应的具体实现类:


然后,在Duck类中加入两个实例变量,分别为FlyBehavior与QuackBehavior接口类型,每个变量会利用多态的方式在运行时引用正确的行为类型。(比如通过构造对象时指定具体行为,也可以通过set方法中途改变行为。)搞定!

回头看一下,每一个Duck都有一个FlyBehavior且有一个QuackBehavior,让Duck将fly和quack委托他们代为处理,将两个类结合起来使用就是组合。这里可以提下第三个设计原则多用组合,少用继承。

这样的设计,可以让fly和quack的动作被其他对象复用,因为这些行为已经与Duck类无关了。而我们可以新增一些行为,不会影响到既有的行为类。这么一来,由了继承的“复用”好处,却没有继承所带来的包袱。

3. 策略模式
上面这个例子完成后,其实我们已经掌握了一个设计模式:策略模式(Strategy Pattern)。把行为抽象为算法。一系列行为其实就是一系列算法,不同的对象使用了不同的算法,不同的策略。
简单定义下:
策略模式定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
对应类图:



讲了优点不讲缺点似乎有点不完整:
策略模式的缺点
1.客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
2.造成很多的策略类。
解决方案:采用工厂模式。

4.总结
1.面向对象基础:抽象,分装,继承,多态
2.目前遇到的3个设计原则:
(1)封装变化,把变化的和不变的分开。
(2)多用组合少用继承。
(3)针对接口编程,不针对实现编程。
3.一个设计模式:策略模式.

主要参考资料:
《HeadFirst》
  • 大小: 54.2 KB
  • 大小: 50.9 KB
  • 大小: 46.5 KB
  • 大小: 87.9 KB
0
1
分享到:
评论

相关推荐

    策略模式 Strategy Pattern

    ### 策略模式 Strategy Pattern #### 概述 策略模式是一种行为设计模式,它使得算法可以在运行时被更改。这种模式允许一个类的行为或其算法在运行时根据需要进行改变,通过这种方式,我们可以轻松地扩展不同的算法...

    【Java设计模式】(2)策略模式Strategy

    策略模式(Strategy)是软件设计模式中的一种行为模式,它使你能在运行时改变对象的行为。在Java中,策略模式通常涉及定义一系列算法,并将每个算法封装起来,使得它们可以相互替换,同时使得算法的变化独立于使用它...

    每天感悟总结-策略模式Strategy

    2009-03-9 策略模式Strategy:当解决一个问题的途径(策略)有很多种的时候,每一种处理方式都可以做为一种处理策略,通过管理类来切换调用不同的策略。

    (行为型模式) Strategy 策略模式

    C#面向对象设计模式 (行为型模式) Strategy 策略模式 视频讲座下载

    策略模式Strategy

    策略模式的主要组件包括上下文(Context)、策略(Strategy)接口以及具体的策略类。上下文是使用策略的对象,它通过策略接口与策略进行交互。策略接口定义了一组操作,这些操作将在不同的策略实现中有所不同。具体策略...

    策略(strategy)模式

    策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。在策略模式中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为模式。 在策略模式中,我们创建表示各种策略的对象和一个行为根据...

    走进设计模式之 策略模式(Strategy)

    策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。在软件设计中,有时我们需要根据不同的场景或条件选择不同的算法或行为。策略模式允许我们将这些算法封装成独立的类,每个类代表一种策略,然后在运行...

    设计模式C++学习之策略模式(Strategy)

    在`Demo1_Strategy`这个示例中,可能包含了多个C++源文件,分别实现了策略模式的不同方面,例如定义了策略接口、具体策略类以及上下文类的实现。通过分析这些源代码,我们可以更深入地理解策略模式的用法和优势。 ...

    PHP设计模式之 策略模式Strategy详解【对象行为型】

    本文实例讲述了PHP设计模式之 策略模式Strategy。分享给大家供大家参考,具体如下: 1.概述  在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法...

    设计模式之策略模式(Strategy Pattern)

    在策略模式中,有三个主要角色:策略接口(Strategy Interface)、具体策略类(Concrete Strategy Classes)和上下文(Context)。策略接口定义了所有支持的算法的公共接口,这样上下文就可以通过这个接口来调用这些...

    策略模式(strategy)

    策略模式的核心组成部分包括策略(Strategy)、上下文(Context)和具体策略(Concrete Strategies)。策略定义了算法家族,而上下文则使用这些策略,但并不知道具体的实现细节。具体策略是实现了策略接口的具体算法...

    设计模式之策略模式(Strategy Pattern)

    策略模式的主要组成部分包括上下文(Context)、策略接口(Strategy Interface)和具体策略类(Concrete Strategy Classes)。上下文维护一个对策略对象的引用,并使用这个引用来调用策略对象的算法。策略接口定义了...

    Java 设计模式-策略模式(Strategy)Android讲解

    首先,策略模式由三个主要组成部分构成:上下文(Context)、策略(Strategy)接口和具体策略(Concrete Strategy)。上下文是使用策略的对象,它维护一个对策略的引用,并调用策略的接口来执行算法。策略接口定义了一组...

    C#面向对象设计模式纵横谈(23):(行为型模式) Strategy 策略模式

    策略模式的核心组成部分包括上下文(Context)、策略(Strategy)和具体策略(Concrete Strategy)。上下文是使用策略的对象,它定义了客户所期望的接口,并负责调用具体策略对象的算法。策略是所有具体策略的抽象接口,它...

    设计模式-策略模式(Strategy)

    策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。这种模式允许你使用算法族,而无需在代码中硬编码这些算法。通过将算法封装到具有共同接口的独立对象中,策略模式使得你可以根据需要灵活地切换算法,...

    [行为模式] head first 设计模式之策略模式(strategy)

    在提供的`strategy.h`文件中,可能包含了策略模式的C++实现。文件中可能定义了策略接口和几个具体策略类的声明,以及上下文类的接口。为了进一步了解其内容,我们需要查看源代码。由于实际的代码没有提供,这里只能...

    详解SpringBoot结合策略模式实战套路

    SpringBoot结合策略模式实战套路 策略模式是一种常用的设计模式,它可以使我们的代码更加灵活、可维护和可扩展。在SpringBoot项目中,策略模式可以与依赖注入机制相结合,实现更加灵活的业务逻辑处理。在本文中,...

    strategy策略模式源码

    策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。...在提供的压缩包文件"strategy"中,可能包含了关于策略模式的示例代码或者详细解释,你可以解压后查看,进一步理解和学习策略模式的实现和应用。

Global site tag (gtag.js) - Google Analytics