What?
Define a family of algorithms, encapsulate each one, and
make them interchangeable. Strategy lets the algorithm
vary independently from the clients that use it. ——GOF
定义一系列算法,封装每一个,并且使每个封装是可相互替换的。Strategy模式,做到了 以独立于使用这些算法的客户端的方式 , 替换这一系列算法算法。自由替换每种算法,不受客户端束缚。
官网实例:
public class TaskController {
public void process () {
// this code is an emulation of a
// processing task controller
// . . .
// figure out which country you are in
CalcTax myTax;
myTax= getTaxRulesForCountry();
SalesOrder mySO= new SalesOrder();
mySO.process(myTax);
}
private CalcTax getTaxRulesForCountry() {
// In real life, get the tax rules based on
// country you are in. You may have the
// logic here or you may have it in a
// configuration file
// Here, just return a USTax so this
// will compile.
return new USTax();
}
}
public class SalesOrder {
public void process (CalcTax taxToUse) {
long itemNumber= 0;
double price= 0;
// given the tax object to use
// . . .
// calculate tax
double tax = taxToUse.taxAmount(itemNumber,price);
}
}
public abstract class CalcTax {
abstract public double taxAmount(long itemSold,double price);
}
public class CanTax extends CalcTax {
public double taxAmount(long itemSold,double price) {
// in real life, figure out tax according to
// the rules in Canada and return it
// here, return 0 so this will compile
return 0.0;
}
}
public class USTax extends CalcTax {
public double taxAmount(long itemSold,double price) {
// in real life, figure out tax according to
// the rules in the US and return it
// here, return 0 so this will compile
return 0.0;
}
}
The Strategy Pattern: Key Features (关键特点)
- Intent(目的):
允许你根据不同的环境(上下文情况),使用不同的业务逻辑或者算法。
Allows you to use different business rules or algorithms depending
upon the context in which they occur.
- Problem(应用场景):
如何选择合适、匹配的算法 取决于客户端的请求或逻辑的执行。假如,你的选择算法唯一,你并不需要Strategy模式。
当分析到 要根据不同情况去选择不同业务方案,考虑下Strategy!
The selection of an algorithm that needs to be applied depends upon
the client making the request or the data being acted upon. If you
simply have a rule in place that does not change, you do not need a
Strategy pattern.
- Solution(具体方案):
将算法的选择与算法的实现分离开来。允许根据上下文去对算法做选择。
Separates the selection of algorithm from the implementation of the
algorithm. Allows for the selection to be made based upon context.
- Participants and Collaborators:
Strategy策略明确了 不同算法被使用的 方式。
1.每个具体的 Stragety 类 实现了 每个具体的算法(或业务逻辑)。
2.上下文Context根据 一个 Strategy类型的引用 来选择 具体的算法( Stragety).也就是说对算法的选择,是Context和Stragety类型的交互结果。
3.Context将来自Clinet的请求转给 Stragety.
The strategy specifies how the different algorithms are used.
? The concreteStrategies implement these different algorithms.
? The Context uses the specific ConcreteStrategy with a reference of
type Strategy. The strategy and Context interact to implement the
chosen algorithm (sometimes the strategy must query the Context).
? The Context forwards requests from its Client to the Strategy.
- Consequences(效果):
1 .Strategy模式 定义了一系列 算法(业务逻辑)
2 .消除 switch、if else 等语句。
3 . 用同一种方式调用所有算法(因为有多态)。算法实现类与Context上下文的交互 也许需要Context调用额外的 Context.getState() 。
4.每个Stragety实现都是一个独立的类,简化了测试的难度。
? The Strategy pattern defines a family of algorithms.
? Switches and/or conditionals can be eliminated.
? You must invoke all algorithms in the same way (they must all have the same interface). The interaction between the ConcreteStrategies and the Context may require the addition of getstate type methods to the Context.
- Implementation
让使用算法的类(Context)包含一个抽象类(Strategy),该抽象类中
有一个抽象方法指定如何调用算法。每个派生类按需要实现算法。
注意:在原型Stragety模式中,选择所用具体实现类的职责由Client对象承担,并转给Strategy模式的Context对象。
Have the class that uses the algorithm (the Context) contain an
abstract class (the stragegy) that has an abstract method pecifying
how to call the algorithm. Each derived class implements the algorithm
as needed. Note: this method wouldn’t be abstract if you wanted to
have some default behavior. Note: In the prototypical Strategy
pattern, the responsibility for selecting the particular
implementation to use is done by the Client object and is given to the
context of the Strategy pattern.
- Strategy与Context的耦合
Strategy模式要求所封装的算法 必须处在 使用他们的类(Context)之外。也就是以为这 要么把Strategy需要的信息传给它(Strategy),要么以其他形式获得。
缺点:
不得不创建多个额外的类。但如果不考虑扩展算法的情况下,可以在抽象类 **Strategy中 用内部类包含所有算法。
版权声明:本文为博主原创文章,未经博主允许不得转载。