Java设计模式 Design Pattern:策略模式 Strategy Pattern

 意图

Define a family of algorithms, encapsulate each one, and make them interchangeable.

定义一组算法,封装每一个算法,并使他们可以互换

Strategy lets the algorithm vary independently from clients that use it.

策略使得算法可以独立于使用它的客户而变化.

 结构

 

Strategy : declares an interface common to all supported algorithms. Context uses this interface to call the algorithm defined by a ConcreteStrategy.

Strategy :为所有支持的策略提供一个公共的接口. Context使用这个接口来调用ConcreteStrategy中定义的一个算法.

ConcreteStrategy : implements the algorithm using the Strategy interface.

ConcreteStrategy :实现Strategy接口的算法

Context : is configured with a ConcreteStrategy object. maintains a reference to a Strategy object. may define an interface that lets Strategy access its data.

Context :配置了一个ConcreteStrategy对象.维护了一个Strategy对象的引用.可能定义了一个接口来使得Strategy可以访问数据.

应用场景

many related classes differ only in their behavior. Strategies provide a way to configure a class with one of many behaviors.

you need different variants of an algorithm. For example, you might define algorithms reflecting different space/time trade-offs. Strategies can be used when these variants are implemented as a class hierarchy of algorithms.

an algorithm uses data that clients shouldn't know about. Use the Strategy pattern to avoid exposing complex, algorithm-specific data structures.

a class defines many behaviors, and these appear as multiple conditional statements in its operations. Instead of many conditionals, move related conditional branches into their own Strategy class.

很多相关的类只是他们的行为不同.策略可为一个类配置多种行为中的一种.

你可能需要一个算法的多种不同的变体.例如,你可能定义算法来反映不同时间地点的交易.当变化使用类层次结构的算法来实现时,可以使用策略模式.

一个算法使用客户不需要知道的数据.使用策略模式可以避免暴露复杂的和数据结构相关的算法.

一个类定义了多种行为,并且这些行为使用了多重的条件语句进行了操作.可以将相关的条件分支放到他们的策略类中来取代众多的条件分支.

影响效果

Families of related algorithms. Hierarchies of Strategy classes define a family of algorithms or behaviors for contexts to reuse. Inheritance can help factor out common functionality of the algorithms.

一组相关的算法.层次结构的算法为上下为定义一组可以重用的算法或行为.继承有助于将算法中公共的功能提取出来.

An alternative to subclassing. Inheritance offers another way to support a variety of algorithms or behaviors. You can subclass a Context class directly to give it different behaviors. But this hardwires the behavior into Context. It mixes the algorithm implementation with Context's, making Context harder to understand, maintain, and extend. And you can't vary the algorithm dynamically. You wind up with many related classes whose only difference is the algorithm or behavior they employ. Encapsulating the algorithm in separate Strategy classes lets you vary the algorithm independently of its context, making it easier to switch, understand, and extend.

一种子类化的选择.继承提供了支持众多算法或行为的另一种方法.可以对Context类直接进行子类化来使它具有不同的行为.但是它将行为在Context中进行了硬编码.它在Context中混合了算法的实现,使得Context很难读懂,维护和扩展.并且你不能动态的改变算法.你最终获得了很多相关的类,他们唯一的区别是他们使用的算法或行为不同.将算法分别封装到不同的Strategy类中可以使你可以独立于上下文而修改算法,使得算法更容易被选择,读懂和扩展.

Strategies eliminate conditional statements. The Strategy pattern offers an alternative to conditional statements for selecting desired behavior. When different behaviors are lumped into one class, it's hard to avoid using conditional statements to select the right behavior. Encapsulating the behavior in separate Strategy classes eliminates these conditional statements.

Strategies消除了条件语句.策略模式提供了一种替代条件语句来选择期望行为的方法.当不同的行为集中到一个类中时,很难避免使用条件语句来选择正确的行为.将行为封装到不同的类中可以去除这些条件语句.

A choice of implementations. Strategies can provide different implementations of the same behavior. The client can choose among strategies with different time and space trade-offs.

实现方式的选择. Strategies可以提供相同行为的不同实现.客户可以在进行不同时间和地点的交易时在策略中进行选择.

 

示例:

参考:http://en.wikipedia.org/wiki/Strategy_pattern#Java

 

 

 

 

 

//StrategyExample test application

 

class StrategyExample {

 

    public static void main(String[] args) {

 

       Context context;

 

       // Three contexts following different strategies

       context = new Context(new ConcreteStrategyAdd());

       int resultA = context.executeStrategy(3, 4);

 

       context = new Context(new ConcreteStrategySubtract());

       int resultB = context.executeStrategy(3, 4);

 

       context = new Context(new ConcreteStrategyMultiply());

       int resultC = context.executeStrategy(3, 4);

 

       System.out.println(resultA);

       System.out.println(resultB);

       System.out.println(resultC);

    }

 

}

 

// The classes that implement a concrete strategy should implement this

 

// The context class uses this to call the concrete strategy

interface Strategy {

 

    int execute(int a, int b);

 

}

 

// Implements the algorithm using the strategy interface

class ConcreteStrategyAdd implements Strategy {

 

    public int execute(int a, int b) {

       System.out.println("Called ConcreteStrategyAdd's execute()");

       return a + b; // Do an addition with a and b

    }

 

}

 

class ConcreteStrategySubtract implements Strategy {

 

    public int execute(int a, int b) {

       System.out.println("Called ConcreteStrategySubtract's execute()");

       return a - b; // Do a subtraction with a and b

    }

 

}

 

class ConcreteStrategyMultiply implements Strategy {

 

    public int execute(int a, int b) {

       System.out.println("Called ConcreteStrategyMultiply's execute()");

       return a * b; // Do a multiplication with a and b

    }

 

}

 

// Configured with a ConcreteStrategy object and maintains a reference to a

// Strategy object

class Context {

 

    private Strategy strategy;

 

    // Constructor

    public Context(Strategy strategy) {

       this.strategy = strategy;

    }

 

    public int executeStrategy(int a, int b) {

       return strategy.execute(a, b);

    }

 

}

 

posted @ 2010-08-22 19:38  OYJJ  阅读(253)  评论(0编辑  收藏  举报