策略模式是行为型设计模式,它允许定义一系列不同的算法,客户端可在不同的算法间轻松切换
1、使用
假设有一套支付系统,用户可以选择不同渠道支付,渠道有微信、支付宝、PayPal
public interface Pay {
void pay();
}
支付宝支付
public class AliPay implements Pay {
@Override
public void pay() {
System.err.println("支付宝支付");
}
}
微信支付
public class WeixinPay implements Pay {
@Override
public void pay() {
System.err.println("微信支付");
}
}
PayPal支付
public class PayPalPay implements Pay {
@Override
public void pay() {
System.err.println("PayPal支付");
}
}
支付策略类
public class PayStrategies {
private Map<String, Pay> payStrategies = new HashMap<>();
public PayStrategies {
payStrategies.put("ali", new AliPay());
payStrategies.put("weixin", new WeiXinPay());
payStrategies.put("paypal", new PayPalPay());
}
public Pay getPay(String strategies) {
Pay pay = payStrategies.get(strategies);
if (pay == null)
throw new IllegalArgumentException();
return pay;
}
}
客户端
public class Client {
public static void main(String[] args) {
PayStrategies ps = new PayStrategies();
Pay pay = ps.getPay("ali");
pay.pay();
}
}
客户端通过传递不同的参数,选择不同的支付方式进行支付
2、常见应用
1、SpringMVC中HandlerMethodArgumentResolver解析入参参数
public interface HandlerMethodArgumentResolver {
/**
* Whether the given {@linkplain MethodParameter method parameter} is
* supported by this resolver.
* @param parameter the method parameter to check
* @return {@code true} if this resolver supports the supplied parameter;
* {@code false} otherwise
*/
boolean supportsParameter(MethodParameter parameter);
/**
* Resolves a method parameter into an argument value from a given request.
* A {@link ModelAndViewContainer} provides access to the model for the
* request. A {@link WebDataBinderFactory} provides a way to create
* a {@link WebDataBinder} instance when needed for data binding and
* type conversion purposes.
* @param parameter the method parameter to resolve. This parameter must
* have previously been passed to {@link #supportsParameter} which must
* have returned {@code true}.
* @param mavContainer the ModelAndViewContainer for the current request
* @param webRequest the current request
* @param binderFactory a factory for creating {@link WebDataBinder} instances
* @return the resolved argument value, or {@code null} if not resolvable
* @throws Exception in case of errors with the preparation of argument values
*/
@Nullable
Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;
}
根据参数类型通过supportsParameter是否支持解析参数,支持的话就可以调用resolveArgument方法进行解析。常见的实现RequestParamMethodArgumentResolver解析带有@RequestParam注解的参数,ServletModelAttributeMethodProcessor解析自定义类型的参数,RequestResponseBodyMethodProcessor解析带有@RequestBody注解的参数
2、Collections.sort(List<T> list, Comparator<? super T> c)方法中,Comparator接口代表着一种排序的抽象策略,可以实现不同的Comparator(推荐使用Lambda实现),拥有不同的排序方式
3、总结
1、优缺点
优点
- 自由选择不同算法
- 符合开闭原则
- 将算法的实现和算法的使用隔离
缺点
- 客户端要知道策略间的不同才能选择不同的算法
2、应用场景
- 希望使用不同的算法,并在运行时可以动态切换,可以使用策略模式
3、模版模式与策略模式
- 模版方式基于继承,只能重写算法中的部分步骤
- 策略模式基于组合,可以重写整个算法
版权声明:本文为weixin_42721350原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。