定义一系列的算法(algorithm family),将每一个算法封装起来,并让它们可以相互替换(interchangeable),策略模式让算法独立于使用它的客户而变化。
类和对象的关系
抽象策略类(Strategy):定义一个公共的接口给所支持的算法。Context使用这个接口调用Concrete Strategy定义的算法。
具体策略类(Concrete Strategy):调用Strategy接口实现具体的算法。
场景(Context):用Concrete Strategy对象配置其执行环境,维护一个对Strategy的引用实例,可以定义一个接口供Strategy存取其数据。
范例
我们打算去机场乘飞机,可以选择很多交通方法。我们可以根据时间要求和乘车费用及方便性而采用不同的策略。
优势和缺陷
策略模式提供了替代派生子类,并定义类的每个行为,剔除了代码中条件的判断语句,使得扩展和结合新的行为变得更容易,根本不需要变动应用程序。策略模式可以避免使用多重田间转移语句,系统变得更加灵活。应用策略模式会长生很多子类,这符合高内聚的责任分配模式。
应用情景
1. 多个类的分别只是在于行为的不同。
2. 你需要对行为的算法做很多变动
3. 客户不知道算法要使用的数据。
Strategy模式使用例子
1. 以不同的格式保存文档
2. 以不同的算法压缩文件
3. 以不同的算法截取图像
在这里以字符串为例,一个文件,我们需要读取后,希望替代其中相应的变量,然后输出。关于替代其中的变量的方法可能有很多种方法,这取决于用户的要求,所以我们要准备几套变量字符代替方案。
定义一个公共的接口给所有支持的算法,这个抽象类Strategy定义了一些方法和变量
|
package StrategyPattern;
publicabstractclass Strategy {
protected String oldString;
protected String newString;
public Strategy(String oldString) {
this.oldString = oldString;
}
public String getNewString() {
returnnewString;
}
//子类继承这个方法,实现不同的替换
publicabstractvoid replay();
}
|
现在又三个字符串的替换方法:
1.”aaa” à “bbb”
2.”aaa” à “ccc”
3.”aaa” à “ddd”
有三个类完成的这样的功能,它们分别是
ConcreteStrategyOne、ConcreteStrategyTwo、ConcreteStrategyThree
这三个类都分别继承了类Strategy,并实现了replay()方法。
|
package StrategyPattern;
publicclass ConcreteStrategyOne extends Strategy {
public ConcreteStrategyOne(String oldString) {
super(oldString);
}
@Override
publicvoid replay() {
newString = oldString.replace("aaa", "bbb");
System.out.println(newString);
System.out.println("successfully replace by one model");
}
}
package StrategyPattern;
publicclass ConcreteStrategyTwo extends Strategy {
public ConcreteStrategyTwo(String oldString) {
super(oldString);
// TODO Auto-generated constructor stub
}
@Override
publicvoid replay() {
// TODO Auto-generated method stub
newString = oldString.replace("aaa", "ccc");
System.out.println(newString);
System.out.println("successfully replace by two medol");
}
}
|
|
package StrategyPattern;
publicclass ConcreteStrategyThree extends Strategy {
public ConcreteStrategyThree(String oldString) {
super(oldString);
// TODO Auto-generated constructor stub
}
@Override
publicvoid replay() {
// TODO Auto-generated method stub
newString = oldString.replace("aaa", "ddd");
System.out.println(newString);
System.out.println("successfull replace by three model");
}
}
|
下面定义一个算法解决类,让用户可以自由的选择算法
|
package StrategyPattern;
publicclass Context {
private Strategy strategy;
ackage StrategyPattern;
publicclass Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
publicvoid getNewContext(String str) {
strategy.replay();
}
publicvoid changeAlgorithm(Strategy strategy) {
this.strategy = strategy;
}
}
|
调试类如下:
|
package StrategyPattern;
publicclass Client {
publicstaticvoid main(String[] args) {
String str = "aaannnnnnnnnnnwwwwwwwww";
Strategy one = new ConcreteStrategyOne(str);
Strategy two = new ConcreteStrategyTwo(str);
Strategy three = new ConcreteStrategyThree(str);
Context context = new Context(one);
context.getNewContext(str);
context.changeAlgorithm(two);
context.getNewContext(str);
context.changeAlgorithm(three);
context.getNewContext(str);
}
}
|
我们达到了在运行期间可以自由的切换算法的目的。
Strategy模式的核心在于抽象类AbstractStrategy类的使用,可以在运行期间实现算法的转换,策略模式在用户需要变化时修改量很少,而且快速。
Strategy模式跟Factory模式有点相像,Strategy模式很容易理解,Strategy模式可以在运行时期自由切换,Factory模式主要是用来创建对象。
本文介绍策略模式的概念及其应用场景,通过一个字符串替换的例子展示了如何利用策略模式实现算法的动态切换,提高软件系统的灵活性。
951

被折叠的 条评论
为什么被折叠?



