策略模式
在《大话设计模式》这本书中,对于策略模式是这么解释的:策略模式定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户。
这么看的话可能有点复杂,但是在java中实际使用以后,我对于设计模式的理解,可以简单的概括为针对某一功能接口的多种实现方案以及调用。
实现方式
概念说完了,接下来就是实现了,其实策略模式的实现方式十分简单,就像上面概括的那样,首先写一个接口,然后根据实际情况对这个接口进行实现,有多少种情况,就写多少个实现类,接下来再为这些实现类建立一个策略上下文,也就是写一类去定义之前那些实现类的调用规则,最后再在客户端需要的时候进行调用就可以了
案例:支付接口
相对于我在设计模式书中看到的商场的例子,我更喜欢用支付接口来作为案例,因为这是我在最近项目切实用到的,体现设计模式最直观的一个案例。
//支付接口
public interface PayStrategy{
public void pay(PayContext context);
}
//支付宝支付实现
public class AliPay implements PayStrategy{
@Override
public void pay(PayContext context){
System.out.println(context.getName()+"使用支付宝支付"+context.getMoney()+"元")
}
}
//微信支付实现
public class WxPay implements PayStrategy{
@Override
public void pay(PayContext context){
System.out.println(context.getName()+"使用微信支付"+context.getMoney()+"元")
}
}
//用户实体类
@Data
public class User{
private String name;
private String money;
}
//支付策略选择逻辑
public class PayContext{
private String name;
private String money;
private PayStrategy payStrategy;
public PayContext (User user,PayStrategy payStrategy ){
this.name=user.getName();
this.money=user.getMoney();
this.payStrategy=payStrategy;
}
public String getName(){
return this.name;
}
public String getMoney(){
return this,money;
}
public void pay(){
return pay(this);
}
}
//对外调用
public class client{
public static void main(String args[]){
PayStrategy ali=new Alipay();
PayStrategy wx=new WxPay();
User ali=new User();
ali.setName("Steve");
ali.setMoney("4000");
User wx=new User();
wx.setName("Jobs");
wx.setMoney("400");
PayContext use1=new PayContext (ali,Ali);
PayContext use2=new PayContext (wx,Wx);
use1.pay();
use2.pay();
}
}//支付接口
public interface PayStrategy{
public void pay(PayContext context);
}
//支付宝支付实现
public class AliPay implements PayStrategy{
@Override
public void pay(PayContext context){
System.out.println(context.getName()+"使用支付宝支付"+context.getMoney()+"元")
}
}
//微信支付实现
public class WxPay implements PayStrategy{
@Override
public void pay(PayContext context){
System.out.println(context.getName()+"使用微信支付"+context.getMoney()+"元")
}
}
//用户实体类
@Data
public class User{
private String name;
private String money;
}
//支付策略选择逻辑
public class PayContext{
private String name;
private String money;
private PayStrategy payStrategy;
public PayContext (User user,PayStrategy payStrategy ){
this.name=user.getName();
this.money=user.getMoney();
this.payStrategy=payStrategy;
}
public String getName(){
return this.name;
}
public String getMoney(){
return this,money;
}
public void pay(){
return pay(this);
}
}
//对外调用
public class client{
public static void main(String args[]){
PayStrategy ali=new Alipay();
PayStrategy wx=new WxPay();
User aliuser=new User();
aliuser.setName("Steve");
aliuser.setMoney("4000");
User wxuser=new User();
wxuser.setName("Jobs");
wxuser.setMoney("400");
PayContext use1=new PayContext (aliuser,Ali);
PayContext use2=new PayContext (wxuser,Wx);
use1.pay();
use2.pay();
}
}
优缺点分析
优点:
降低了使用if-else所带来的代码耦合性,有利于代码维护
提高的了代码的可扩展性,相比于if-else,使用策略模式对后续功能的添加只需要实现接口就行了
缺点:
context在使用策略类的时候,由于实现了策略接口,所以有些用不到的数据依旧会被初始化
策略类太多,每个策略都是一个类,可复用性不高
所有策略类都需要对外暴露,也就是客户端需要知道所有的策略类
- 因为只接触过java一种语言,所以在接触到策略模式的时候会下意识的以为策略模式的实现是基于java的多态性的,但是实际上,很多不支持多态的语言依旧可以使用策略模式,java的多态性只是为策略模式的实现提供了便利