笔者借鉴了《研磨设计模式》中的策略模式,在此做一个总结,以便自己查阅。
1.策略模式的定义:
定义一系列的算法,并把这些算法各自独立的在类中实现,使得客户可以任意调用一个或多个算法。2.策略模式主要解决什么样的问题
策略模式主要的目的是将使用算法的客户和算法分开并独立出来。使得客户可以任意的调用某种算法。
每个计算方式做成一个单独的算法类,从而形成一系列的算法,并且为这一系列算法定义一个公共的接口,这些算法实现是同一接口的不同实现,地位是平等的,可以相互替换。这样一来,要扩展新的算法就变成了增加一个新的算法实现类,要维护某个算法,也只是修改某个具体的算法实现即可,不会对其它代码造成影响。也就是说这样就解决了可维护、可扩展的问题。
3.策略模式的角色
Strategy:
策略接口,用来约束一系列具体的策略算法。Context使用这个接口来调用具体的策略实现定义的算法。
ConcreteStrategy:
具体的策略实现,也就是具体的算法实现。
Context:
上下文,负责和具体的策略类交互,通常上下文会持有一个真正的策略实现,上下文还可以让具体的策略类来获取上下文的数据,甚至让具体的策略类来回调上下文的方法。
4.代码举例
公司里的员工根据不同的职位有不同的工资计算方法,现在针对不同的职位来实现不同的工资计算方法。客户在调用接口的时候只要指明某个员工的职位,Context就会去调用此职位对应的工资计算方法。以下是代码:
public interface Strategy {
/**
* 计算公司职员工资的具体方法
* @return
*/
String calculatePay();
}
每种具体的职位的工资计算类的实现:
/**
*总裁的工资计算类
*/
public class Prisident implements Strategy {
@Override
public String calculatePay() {
return "Get Prisident pay.";
}
}
/**
* 经理的工资计算类
*/
public class Manager implements Strategy {
@Override
public String calculatePay() {
return "Get Manager pay.";
}
}
/**
* 普通员工的工资计算类
*
*/
public class Staff implements Strategy {
@Override
public String calculatePay() {
return "Get Staff pay.";
}
}
Context的实现:
/**
* 上下文对象,通常会持有一个具体的策略对象
*/
public class Context {
private Strategy strategy ;
public Context(Strategy strategy)
{
this.strategy = strategy;
}
/**
* 上下文对客户端提供的操作接口
* @param strategy 客户端指定的具体的工资计算类
* @return
*/
public String calculatePay(Strategy strategy)
{
return strategy.calculatePay();
}
}
测试类:
/**
* test
*/
public class TestStrategy {
public static void main(String args[])
{
//计算Prisident的工资
Strategy prisident = new Prisident();
String prisident_pay = prisident.calculatePay();
//计算Manager的工资
Strategy manager = new Manager();
String manager_pay = manager.calculatePay();
//计算一般员工staff的工资
Strategy staff = new Staff();
String staff_pay = staff.calculatePay();
System.out.println(prisident_pay);
System.out.println(manager_pay);
System.out.println(staff_pay);
}
}
结果显示:
Get Prisident pay.
Get Manager pay.
Get Staff pay.
5、扩展
如果想增加一种职位的工资计算方法,比如Salesman,直接实现一个Salesman类,实现接口Strategy的方法calculatePay()即可。不会对现有的其他类造成影响。