策略模式(Strategy Pattern):定义一族算法类,将每个算法分别封装起来,让它们可以互相替换。
策略模式优点
①、算法可以自由切换
这是策略模式本身定义的, 只要实现抽象策略, 它就成为策略家族的一个成员, 通过封装角色对其进行封装, 保证对外提供“可自由切换”的策略。
②、避免使用多重条件判断
简化多重if-else,或多个switch-case分支。
③、扩展性良好
增加一个策略,只需要实现一个接口即可。
策略模式使用场景
①、多个类只有在算法或行为上稍有不同的场景。
②、算法需要自由切换的场景。
③、需要屏蔽算法规则的场景。
策略模式的定义
①、Context封装角色
它也叫做上下文角色, 起承上启下封装作用, 屏蔽高层模块对策略、 算法的直接访问,封装可能存在的变化。
②、Strategy 抽象策略角色
策略、 算法家族的抽象, 通常为接口, 定义每个策略或算法必须具有的方法和属性。
③、ConcreteStrategy 具体策略角色
实现抽象策略中的操作, 该类含有具体的算法。
在跨国公司中,一般都会在各个国家和地区设置分支机构,聘用当地人为员工,这样就有这样一个需要:每月发工资的时候,中国国籍的员工要发人民币,美国国籍的员工要发美元,英国国籍的要发英镑
支付策略接口
public interface PayStrategy {
//在支付策略接口的支付方法中含有支付上下文作为参数,以便在具体的支付策略中回调上下文中的方法获取数据
public void pay(PayContext ctx);
}
//人民币支付策略
public class RMBPay implements PayStrategy {
@Override
public void pay(PayContext ctx) {
System.out.println("现在给:"+ctx.getUsername()+" 人民币支付 "+ctx.getMoney()+"元!");
}
}
//日元支付策略
public class DollarPay implements PayStrategy {
@Override
public void pay(PayContext ctx) {
System.out.println("现在给:"+ctx.getUsername()+" 日元支付 "+ctx.getMoney()+"dollar !");
}
}
上下文选择不同的策略
//支付上下文,含有多个算法的公有数据
public class PayContext {
//员工姓名
private String username;
//员工的工资
private double money;
//支付策略
private PayStrategy payStrategy;
public void pay(){
//调用具体的支付策略来进行支付
payStrategy.pay(this);
}
public PayContext(String username, double money, PayStrategy payStrategy) {
this.username = username;
this.money = money;
this.payStrategy = payStrategy;
}
public String getUsername() {
return username;
}
public double getMoney() {
return money;
}
}
具体操作
//外部客户端
public class Client {
public static void main(String[] args) {
//创建具体的支付策略
PayStrategy rmbStrategy = new RMBPay();
PayStrategy dollarStrategy = new DollarPay();
//准备小王的支付上下文
PayContext ctx = new PayContext("小王",30000,rmbStrategy);
//向小王支付工资
ctx.pay();
//准备Jack的支付上下文
ctx = new PayContext("jack",10000,dollarStrategy);
//向Jack支付工资
ctx.pay();
}
}
控制台输出
现在给:小王 人民币支付 30000.0元!
现在给:jack 日元支付 10000.0 !
或许看到这里有些人会认为策略模式和工厂模式一样,都是选中一个具体的实现
两者的差异
1.用途不一样
工厂是创建型模式,它的作用就是创建对象;
策略是行为型模式,它的作用是让一个对象在许多行为中选择一种行为;
2.关注点不一样
一个关注对象创建
一个关注行为的封装
3.解决不同的问题
工厂模式是创建型的设计模式,它接受指令,创建出符合要求的实例;它主要解决的是资源的统一分发,将对象的创建完全独立出来,让对象的创建和具体的使用客户无关。主要应用在多数据库选择,类库文件加载等。
策略模式是为了解决的是策略的切换与扩展,更简洁的说是定义策略族,分别封装起来,让他们之间可以相互替换,策略模式让策略的变化独立于使用策略的客户