Strategy 模式
文章出自:http://blog.csdn.net/wy818/archive/2009/04/09/4056149.aspx
优先考虑使用策略模式,而不是具体继承 (Rod)
产生的原因: 属于对象的行为模式。处理多于一个算法时候,把算法和使用算法的客户端分开(把行为和环境分割开),从而方便的选择其中一个算法。
设现在要设计一个贩卖各类书籍的电子商务网站的购物车(Shopping Cat)系统。一个最简单的情况就是把所有货品的单价乘上数量,但是实际情况肯定比这要复杂。比如,本网站可能对所有的教材类图书实行每本一元的折扣;对连环画类图书提供每本7%的促销折扣,而对非教材类的计算机图书有3%的折扣;对其余的图书没有折扣。由于有这样复杂的折扣算法,使得价格计算问题需要系统地解决。
使用策略模式可以把行为和环境分割开来。环境类负责维持和查询行为类,各种算法则在具体策略类(ConcreteStrategy)中提供。由于算法和环境独立开来,算法的增减、修改都不会影响环境和客户端。当出现新的促销折扣或现有的折扣政策出现变化时,只需要实现新的策略类,并在客户端登记即可。策略模式相当于"可插入式(Pluggable)的算法"。
程序架构:一个客户类,一个抽象策略类(接口),若干个具体策略类。由客户类决定选择那一个具体类。
定义一系列的算法,把他们一个个封装起来,并且使它们可相互替换。Strategy模式使算法可独立于使用它的客户而变化。
策略模式是对算法的包装,是把使用算法的责任和算法本身分割开,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是:"准备一组算法,并将每一个算法封装起来,使得它们可以互换。"
策略又称做政策(Policy)模式【GOF95】。下面是一个示意性的策略模式结构图:
这个模式涉及到三个角色:
· 环境(Context)角色:持有一个Strategy类的引用。
· 抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
· 具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。
Strategy模式以下列几条原则为基础:
1) 每个对象都是一个具有职责的个体。
2) 这些职责不同的具体实现是通过多态的使用来完成的。
3) 概念上相同的算法具有多个不同的实现,需要进行管理
通过以下步骤,开发人员可以很容易地在软件中实现策略模型:
1)对策略对象定义一个公共接口。
2)编写策略类,该类实现了上面的公共接口。
3)策略对象的类中保存一个对策略对象的引用。
4)略对象的类中,实现对策略对象的set和get方法。
例:
首先,我们建立一个抽象类RepTempRule 定义一些公用变量和方法:
public abstract class RepTempRule{
protected String oldString=""; public void setOldString(String oldString){ this.oldString=oldString; }
protected String newString=""; public String getNewString(){ return newString; }
public abstract void replace() throws Exception;
}
|
在RepTempRule中 有一个抽象方法abstract需要继承明确,这个replace里其实是替代的具体方法.
我们现在有两个字符替代方案,
1.将文本中aaa替代成bbb;
2.将文本中aaa替代成ccc;
对应的类分别是RepTempRuleOne RepTempRuleTwo
public class RepTempRuleOne extends RepTempRule{
public void replace() throws Exception{
//replaceFirst是jdk1.4新特性 newString=oldString.replaceFirst("aaa", "bbbb") System.out.println("this is replace one"); }
}
|
public class RepTempRuleTwo extends RepTempRule{
public void replace() throws Exception{
newString=oldString.replaceFirst("aaa", "ccc") System.out.println("this is replace Two"); }
}
|
第二步:我们要建立一个算法解决类,用来提供客户端可以自由选择算法。
public class RepTempRuleSolve {
private RepTempRule strategy;
public RepTempRuleSolve(RepTempRule rule){ this.strategy=rule; }
public String getNewContext(Site site,String oldString) { return strategy.replace(site,oldString); }
public void changeAlgorithm(RepTempRule newAlgorithm) { strategy = newAlgorithm; }
}
|
调用如下:
public class test{
......
public void testReplace(){
//使用第一套替代方案 RepTempRuleSolve solver=new RepTempRuleSolve(new RepTempRuleOne()); solver.getNewContext(site,context);
//使用第二套
solver=new RepTempRuleSolve(new RepTempRuleTwo()); solver.getNewContext(site,context);
}
.....
}
|
我们达到了在运行期间,可以自由切换算法的目的。
实际整个Strategy的核心部分就是抽象类的使用,使用Strategy模式可以在用户需要变化时,修改量很少,而且快速.
Strategy和Factory有一定的类似,Strategy相对简单容易理解,并且可以在运行时刻自由切换。Factory重点是用来创建对象。
Strategy适合下列场合:
1.以不同的格式保存文件;
2.以不同的算法压缩文件;
3.以不同的算法截获图象;
4.以不同的格式输出同样数据的图形,比如曲线 或框图bar等
策略模式的优点和缺点
策略模式有很多优点和缺点。它的优点有:
1. 策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免重复的代码。
2. 策略模式提供了可以替换继承关系的办法。继承可以处理多种算法或行为。如果不是用策略模式,那么使用算法或行为的环境类就可能会有一些子类,每一个子类提供一个不同的算法或行为。但是,这样一来算法或行为的使用者就和算法或行为本身混在一起。决定使用哪一种算法或采取哪一种行为的逻辑就和算法或行为的逻辑混合在一起,从而不可能再独立演化。继承使得动态改变算法或行为变得不可能。
3. 使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重转移语句里面,比使用继承的办法还要原始和落后。
策略模式的缺点有:
1. 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。
2. 策略模式造成很多的策略类。有时候可以通过把依赖于环境的状态保存到客户端里面,
其它
策略模式与很多其它的模式都有着广泛的联系。Strategy很容易和Bridge模式相混淆。虽然它们结构很相似,但它们却是为解决不同的问题而设计的。Strategy模式注重于算法的封装,而Bridge模式注重于分离抽象和实现,为一个抽象体系提供不同的实现。Bridge模式与Strategy模式都很好的体现了"Favor composite over inheritance"的观点。
推荐大家读一读《IoC 容器和Dependency Injection 模式》,作者Martin Fowler。网上可以找到中文版的PDF文件。为策略模式的实施提供了一个非常好的方案。
分享到:
相关推荐
实验一 Strategy模式的应用 某公司专门销售各种打印机,销售打印机时都有一定的折扣让利给顾客,但折扣计算的方法有很多种,如:不打折;每台减扣固定的金额;按售价的5%打折等等,且折扣计算方法可能发生变化。...
Strategy模式是一种行为设计模式,它使你能在运行时改变对象的行为。这种模式的核心思想是将算法族封装在独立的对象中,使得它们可以互换使用,让算法的变化独立于使用算法的客户。 在上述的国际电子商务系统案例中...
Strategy模式是一种设计模式,主要目的是为了在运行时动态地改变对象的行为。在本文中,我们将通过一个奇幻角色扮演游戏(RPG)的例子来解释这个模式,以便更好地理解其工作原理。 在RPG游戏中,我们有四种角色:...
策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。在策略模式中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为模式。 在策略模式中,我们创建表示各种策略的对象和一个行为根据...
在“一个strategy模式的例子.rar_strategy_设计模式”这个压缩包中,包含了两个关键文件,一个是“www.pudn.com.txt”,可能是相关资料链接或介绍,另一个是“strategy”,可能是一个具体的策略模式实现代码。...
Strategy模式封装算法。如果有多个算法可以互换使用,Strategy比较合适。 Bridge模式是对抽象和具体的进一步抽象。
在软件设计领域,Strategy模式是一种行为设计模式,它使你能在运行时改变对象的行为。Java作为面向对象编程语言,提供了丰富的特性支持这一模式的应用。在这个小型电子商务系统简单模拟项目中,我们利用Strategy模式...
Strategy模式是设计模式中的一种行为模式,它允许在运行时动态地改变对象的行为。这种模式的核心思想是定义一系列算法,并将每一个算法封装起来,使它们可以相互替换,让算法的变化独立于使用算法的客户。在C++中...
策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。在策略模式中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为模式。 在策略模式中,我们创建表示各种策略的对象和一个行为根据...
设计模式体现的是一种思想,而思想则是指导行为的一切,理解和掌握了设计模式,并不是说记住了23种(或更多)设计场景和解决策略(实际上这也是很重要的一笔财富),实际接受的是一种思想的熏陶和洗礼,等这种思想...
这些类可能分布在不同的包或目录下,例如`com.example.designpattern.strategy`,并且可能还有测试类来验证策略模式的正确性。 在实际应用中,策略模式有以下几个优点: - **封装变化**:每个策略类都封装了一种...
Strategy模式是一种行为设计模式,它使你能在运行时改变对象的行为。在Java中,Strategy模式的核心思想是定义一系列算法,并将每一个算法封装起来,使它们可以互相替换,让算法独立于使用它的客户而变化。 在给出的...
策略模式是一种行为设计模式,它使你能在运行时改变对象的行为。在上述的"打印机销售折扣计算"问题中,策略模式能很好地解决需求变化带来的挑战。通过策略模式,我们可以将每种折扣计算方法封装为一个独立的类,这些...
Strategy模式提供了一种将算法族封装到各自独立的对象中,使得它们可以互换使用的方法。这样,我们可以避免硬编码特定的算法,而是让代码更加灵活,易于扩展。 在本范例中,我们将重点讨论如何应用Strategy模式来...
设计一个邮寄包裹的收费系统,在邮寄类型确定的情况下,包裹的邮资由包裹的重量a,邮寄距离b,保价金额c三个参数决定。系统使用图形用户界面,用户在图形用户界面选择邮寄类型,再输入重量、距离和报价金额,单击...
**策略模式(Strategy Pattern)**是面向对象设计模式中的一种行为模式,它允许在运行时改变对象的行为。在Java编程中,策略模式被广泛应用于处理算法的可互换性问题,使得程序能够根据不同的环境或者需求选择合适的...
这个压缩包文件“设计模式之_Strategy_00_源码与文档.rar”包含了关于Strategy模式的源码实现和相关文档,便于深入理解和学习。 Strategy模式的核心思想是定义一系列算法,并将每一个算法封装起来,使它们可以相互...
Java设计模式中的Strategy模式是一种对象行为型模式,其主要目的是定义一系列算法,并将这些算法封装成独立的类,使得它们可以互相替换,让算法的变化独立于使用算法的客户。在Strategy模式中,核心思想是封装可能...