一. 简述
策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一 个抽象策略类的子类。
属于行为型模式。
二. 组成
- 抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
- 具体策略角色:包装了相关的算法和行为。
- 环境角色:持有一个策略类的引用,最终给客户端调用。
三. UML类图
四. 基本代码
// 抽象策略类
public interface DatabaseStrategy {
public void process();
}
// 具体策略类
public class MysqlDBStrategy implements DatabaseStrategy {
public void process() {
System.out.println("处理Mysql数据库连接");
}
}
public class OracleDBStrategy implements DatabaseStrategy {
public void process() {
System.out.println("处理Oracle数据库连接");
}
}
// Context类
public class DataBaseManager {
public void process(DatabaseStrategy dbStrategy) {
dbStrategy.process();
}
}
// 客户端调用
public class StrategyClient {
public static void main(String[] args) {
DataBaseManager manager = new DataBaseManager();
MysqlDBStrategy mysql = new MysqlDBStrategy();
manager.process(mysql);
OracleDBStrategy oracle = new OracleDBStrategy();
manager.process(oracle);
}
}
五. 优缺点
优点
- 策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免代码重复。
- 使用策略模式可以避免使用多重条件(if-else)语句。多重条件语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重条件语句里面,比使用继承的办法还要原始和落后。
缺点
- 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道算法或行为的情况。
- 由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数目就会很可观。
六. 应用场景
- 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
- 需要在不同情况下使用不同的算法(策略),或者策略还可能在未来用其它方式来实现。
只要在分析过程中听到需要在不同时间应用不同的业务规则,就可以考虑使用策略模式。
例:商场促销例子:对初级会员没有折扣;对中级会员提供10%的促销折扣;对高级会员提供20%的促销折扣... ...