本文介绍策略模式的结构、一个demo、基本应用场景、优缺点
简介
Strategy模式-行为模式的一种
- 对一系列算法封装,为所有算法定义一个抽象的算法接口,并通过集成该抽象算法接口对所有的算法加以封装和实现,具体的算法选择由客户端(使用处)来决定(策略)。
主要用于平滑的处理算法的切换
结构图
角色和职责
- Strategy:策略(算法)的抽象
- ConcreateStrateggy:各种策略(算法)的具体实现
- Context:策略的外部封装类,或者说策略的容器类。根据不同策略执行不同的行为,策略由外部环境(使用者)决定。此Context也可以看做对外的一个工厂,此工厂向外根据不同策略提供不同方法。
使用场景
一般使用在具体执行方法可变/多变的场景中
- 算法选择(加密算法)
- 折扣方式选择(折扣额度)
等等场景
实现
package com.mym.designmodel;
/**
* 职责:策略的抽象
*/
public interface Strategy {
public void encrypt();
}
第一个实现类(策略)
package com.mym.designmodel;
/**
* 职责:ConcreateStrateggy。各种策略(算法)的具体实现
*/
public class MD4Strategy implements Strategy{
@Override
public void encrypt() {
System.out.println("this is MD4Strategy!");
}
}
第二个实现类(策略)
package com.mym.designmodel;
/**
* 职责:ConcreateStrateggy。各种策略(算法)的具体实现
*/
public class MD5Strategy implements Strategy{
@Override
public void encrypt() {
System.out.println("this is MD5Strategy!");
}
}
策略容器
package com.mym.designmodel;
/**
* Context:策略的外部封装类,或者说策略的容器类。根据不同策略执行不同的行为,策略由外部环境(使用者)决定
*/
public class Context {
Strategy strategy = null;
public Context(Strategy strategy){
this.strategy = strategy;
}
/**执行方法*/
public void encrypt(){
this.strategy.encrypt();
}
}
测试:
package com.mym.designmodel;
/**
* 测试
*/
public class MainClass {
public static void main(String[] args) {
Context context = new Context(new MD5Strategy());
context.encrypt();
}
}
测试结果:
this is MD5Strategy!
换成
Context context = new Context(new MD4Strategy());
则执行结果为:
this is MD4Strategy!
优点
- 策略模式是一个管理算法族的方式。它的登记结构定义了一个算法或行为族。恰当的使用集成可把公共的代码转移到父类里面,从而避免重复的代码
- 策略模式提供可以替换继承关系的方法。继承可以护理多种算法或行为。如果不用策略模式,那么使用算法或行为的环境类就可能会有一些子类,每一个子类提供一个不同的算法或行为。但是,这样过算法或行为的使用者就和算法或行为本身混在一起。决定使用哪一种算法或采取哪一种行为的逻辑就和算法或行为的逻辑混合在一起,从而不可能给再独立演化。集成使得动态改变算法或行为变得不可能。
3.策略模式可以避免使用多重条件转移语句。多重条件转移语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为混合在一起,统统列在一个多重转移语句中,比使用继承的办法还要原始和落后。
缺点
- 客户端必须知道所有的策略类,并自行决定使用你一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。也就是说,策略模式只适用于客户端知道所有算法或行为的情况。(可理解为:自己设计自己用的情况)
- 策略模式造成很多策略类。有时候可以通过把依赖于环境的状态保存到客户端中,而将策略类设计成可共享的,这样策略类实例可以被不同客户端使用。也就是说,可以使用享元模式来减少对象的数量。