码迷,mamicode.com
首页 > 其他好文 > 详细

策略模式(Strategy Pattern)

时间:2014-09-20 15:13:27      阅读:187      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   color   使用   java   ar   strong   数据   

Contents of  Strategy Pattern:

  概念;组成;应用场景;意义;实现;编写步骤;优缺点;简单实现。

概念:

  The Strategy Pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

  策略模式定义了一系列的算法(算法族),并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

  策略模式中体现了两个非常基本的面向对象设计的原则——封装变化的概念;编程中使用接口,而不是对接口的实现(面向接口的编程)。

组成:

  • 抽象策略角色(Strategy):策略类,通常由一个接口或者抽象类实现——各种不同的算法以不同的方式实现这个接口,Context使用这个接口调用不同的算法。      
  • 具体策略角色(ConcreteStrategy):实现了Strategy定义的接口,提供具体的算法实现(包装了相关的算法和行为)。
  • 环境角色(Context):持有一个策略类的引用,最终给客户端调用——内部维护一个Strategy实例,需要使用ConcreteStrategy提供的算法。负责动态设置运行时Strategy具体的实现算法,跟Strategy之间的交互和数据传递。

应用场景:

  1、多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。

  2、需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。

  3、对客户隐藏具体策略(算法)的实现细节,彼此完全独立。

意义:

  策略模式使开发人员能够开发出由许多可替换的部分组成的软件,并且各个部分之间是弱连接的关系。弱连接的特性使软件具有更

  强的可扩展性,易于维护,更重要的是,它大大提高了软件的可重用性。

实现:

  1、策略模式的用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得他们可以相互替换。

  2、策略模式使得算法可以在不影响客户端的情况下发生变化。使用策略模式可以把行为和环境分隔开来。

  3、环境类负责维持和查询行为类,各种算法则在具体策略中提供。由于算法和环境独立开来,算法的修改不会影响环境和客户端。   

编写步骤:

  1、对策略对象定义一个公共接口。

  2、编写策略类,该类实现了上面的公共接口。

  3、在使用策略对象的类中保存一个对策略对象的引用。

  4、在使用策略对象的类中,实现对策略对象的set和get方法(注入)或者使用构造方法完成赋值。 

优缺点:

 优点:

  1、策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码转移到

     父类里面,从而避免重复的代码。

  2、策略模式提供了可以替换继承关系的办法。即保持了继承的优点(代码重用),还比继承更灵活(算法独立,可以任意扩展)。

     继承可以处理多种算法或行为。如果不使用策略模式,那么使用算法或行为的环境类可能会有一些子类,每一个子类提供一个不

     同的算法或行为。但是,这样一来算法或行为的使用者就和算法或行为本身混在一起 决定使用哪一种算法或采取哪一种行为的逻

     辑就和算法或行为的逻辑混合在一起,从而不可能再独立演化。继承使得动态改变算

     法或行为变得不可能。

  3、使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或

     行为的逻辑混合在一起,统统列在一个多重转移语句里面,比使用继承的办法还要原始和落后。 

 缺点:

  1、客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当

     的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。

  2、策略模式造成很多的策略类,每个具体策略类都会产生一个新类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将

     策略类设计成可共享的,这样策略类实例就可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量。

一个简短的实例:

/**
 * 实现策略模式:
 * 类比于TreeMap的实现,Comparator相当于抽象策略角色(Strategy),实现了Comparator接口的类相当于具体策略角色
 * (ConcreteStrategy),TreeMap相当于环境角色(Context/Environment),持有一个策略类的引用,最终给客户端调用(Client)。
 */

package blogandtest;

public class StrategyTest//The client is used to test the pattern
{
	public static void main(String[] args)
	{
		AddStrategy addStrategy = new AddStrategy();
		Environment environment = new Environment(addStrategy);
		System.out.println("Result of Add:" + environment.calculate(3, 4));
		
		SubtractStrategy subtractStrategy = new SubtractStrategy();
		environment.setStrategy(subtractStrategy);
		System.out.println("Result of Subtract:" + environment.calculate(3, 4));
		
		MultiplyStrategy multiplyStrategy = new MultiplyStrategy();
		environment.setStrategy(multiplyStrategy);
		System.out.println("Result of Multiply:" + environment.calculate(3, 4));
		
		DivideStrategy divideStrategy = new DivideStrategy();
		environment.setStrategy(divideStrategy);
		System.out.println("Result of Divide:" + environment.calculate(3, 4));
	}
}

/**
 * The classes that implement a concrete strategy shoud implement this interface.
 * The Context class uses this to call the concrete strategy.
 */

interface Strategy//analogy interface Comparator
{
	public int calculate(int a, int b);
}

/**
 * Implements the algorithm using the strategy inteface.
 */
class AddStrategy implements Strategy//analogy Comparator‘s implementing class
{
	public int calculate(int a, int b)
	{
		return a + b;
	}
}

class SubtractStrategy implements Strategy
{
	public int calculate(int a, int b)
	{
		return a - b;
	}
}

class MultiplyStrategy implements Strategy
{
	public int calculate(int a, int b)
	{
		return a * b;
	}
}

class DivideStrategy implements Strategy
{
	public int calculate(int a, int b)
	{
	
		return a / b;
	}

}

/**
 * Configured with a ConcreteStrategy object and maintains a reference to a Strategy object
 */
class Environment//analogy TreeMap;
{
	
	private Strategy strategy;
	
	public Environment(Strategy strategy)
	{
		this.strategy = strategy;
	}
	
	public Strategy getStrategy()
	{
		return strategy;
	}

	public void setStrategy(Strategy strategy)
	{
		this.strategy = strategy;
	}


	public int calculate(int a, int b)
	{
		return strategy.calculate(a, b);//Tips:光标放在calculate上按住Ctrl键同时左键点击跳转到Interface Strategy中的抽象方法calculate中;鼠标放上,ctrl+t列出所有的Interface Strategy的实现类。
	}
}

/*
在Eclipse中的输出结果是:
Result of Add:7
Result of Subtract:-1
Result of Multiply:12
Result of Divide:0
*/

 

策略模式(Strategy Pattern)

标签:des   style   blog   color   使用   java   ar   strong   数据   

原文地址:http://www.cnblogs.com/xpjiang/p/3982695.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!