Spring中使用设计模式(一、策略模式)
前几天看到新来的同事桌上有一本设计模式的书,想起许多年前自己啃厚厚的模式时,始终昏昏欲睡,不得要领那段时光。重整思路,结合Spring,写下现在在开发中常用的设计模式使用方式。
策略模式
在工作中最常用的就是策略模式了,也可以说是策略模式的简化版。客户端可以决定用那种策略,调用上下文,上下文使用具体策略做具体的处理。
策略模式的本质是,分离算法,选择实现。如果没有中间的上下文,用接口抽象出策略的行为,客户端调用即可。
举例说明:常见的业务场景是提供给客户的接口文档支持多种支付方式,由客户选择使用哪种支付方式。如客户上送WX,则服务端用微信支付,客户上送ZFB,则服务端用支付宝支付。
以终为始,先上客户端测试代码,具体如下:
@Test
void should_get_select_PayMethod_when_client_selected_some_pay_method() {
ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
PayContext paycontext = context.getBean(PayContext.class);
String wx = paycontext.pay("WX");
assertEquals("微信",wx);
String zfb = paycontext.pay("ZFB");
assertEquals("支付宝",zfb);
}
那么客户端需要许多写if else来支持么?不必,使用策略模式,或者重构出接口,再使用Spring Bean的构造,通过map管理各个策略组件。客户选择哪种支付方式,从map中get出来就OK。
上下文中维护策略map,具体如下:
@Service
public class PayContext {
private static Map<IPayStr.PayType, IPayStr> payRepositoryMap= new HashMap<>();
public PayContext(List<IPayStr> payStrList) {
payStrList.forEach( one ->{
payRepositoryMap.put(one.defindeType(), one);
});
}
public String pay(String payType) {
return payRepositoryMap.get(Enum.valueOf(IPayStr.PayType.class,payType) ).pay();
}
}
IPayStr是支付方式的接口,所有具体的支付方式都有pay()一种行为。
public interface IPayStr {
String pay();
PayType defindeType();
enum PayType{
ZFB("zfb","支付宝"), WX("wx","微信");
private String type, desc;
PayType(String type, String desc) {
this.type = type;
this.desc = desc;
}
public String getDesc() {
return desc;
}
}
}
上下文中map的Key是什么呢?就是客户传过来的报文中的枚举值(实际项目中可能有更多种组合方式)。在接口里可使用defindeType(),规定各个实现类必须初始化一个不重复的值即可。
@Component
public class WxPayStrImpl implements IPayStr {
@Override
public String pay() {
return PayType.WX.getDesc();
}
@Override
public PayType defindeType() {
return PayType.WX;
}
}
这样,代码中没有显示的if else,如果添加更多种支付方式,实现IPayStr,再新写一种枚举值即可。