策略模式(Strategy Pattern)

 

定义一系列的算法(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;
 
public abstract class Strategy {
    protected String oldString ;
    protected String newString ;
   
    public Strategy(String oldString) {
       this . oldString = oldString;
    }
   
    public String getNewString() {
       return newString ;
    }
   
    // 子类继承这个方法,实现不同的替换
    public abstract void replay();
}

 
现在又三个字符串的替换方法:
1.”aaa” à “bbb”
2.”aaa” à “ccc”
3.”aaa” à “ddd”
有三个类完成的这样的功能,它们分别是
ConcreteStrategyOne ConcreteStrategyTwo ConcreteStrategyThree
这三个类都分别继承了类 Strategy ,并实现了 replay() 方法。
 

package StrategyPattern;
 
public class ConcreteStrategyOne extends Strategy {
 
    public ConcreteStrategyOne(String oldString) {
       super (oldString);
    }
 
    @Override
    public void replay() {
       newString = oldString .replace( "aaa" , "bbb" );
       System. out .println( newString );
       System. out .println( "successfully replace by one model" );
    }
   
}
package StrategyPattern;
 
public class ConcreteStrategyTwo extends Strategy {
 
    public ConcreteStrategyTwo(String oldString) {
       super (oldString);
       // TODO Auto-generated constructor stub
    }
 
    @Override
    public void 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;
 
public class ConcreteStrategyThree extends Strategy {
 
    public ConcreteStrategyThree(String oldString) {
       super (oldString);
       // TODO Auto-generated constructor stub
    }
 
    @Override
    public void 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;
 
public class Context {
    private Strategy strategy ;
ackage StrategyPattern;
 
public class Context {
    private Strategy strategy ;
   
    public Context(Strategy strategy) {
       this . strategy = strategy;
    }
   
    public void getNewContext(String str) {
       strategy .replay();
    }
   
    public void changeAlgorithm(Strategy strategy) {
       this . strategy = strategy;
    }
}

 
调试类如下:

package StrategyPattern;
 
public class Client {
    public static void 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 模式主要是用来创建对象。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值