策略模式
经常在网上看到一些名为“别再if-else走天下了”,“教你干掉if-else”等之类的文章,大部分都会讲到用策略模式去代替if-else。策略模式实现的方式也大同小异。主要是定义统一行为(接口或抽象类),并实现不同策略下的处理逻辑(对应实现类)。客户端使用时自己选择相应的处理类,利用工厂或其他方式。
注解实现
本文要说的是用注解实现策略模式的方式,以及一些注意点。
话不多说,还是以最常 见的订单处理为例。首先定义这样一个订单实体类:
@Data
public class Order {
/**
* 订单来源
*/
private String source;
/**
* 支付方式
*/
private String payMethod;
/**
* 订单编号
*/
private String code;
/**
* 订单金额
*/
private BigDecimal amount;
// ...其他的一些字段
}
假如对于不同来源(pc端、移动端)的订单需要不同的逻辑处理。项目中一般会有OrderService这样一个类,如下,里面有一坨if-else的逻辑,目的是根据订单的来源的做不同的处理。
@Service
public class OrderService {
public void orderService(Order order) {
if(order.getSource().equals("pc")){
// 处理pc端订单的逻辑
}else if(order.getSource().equals("mobile")){
// 处理移动端订单的逻辑
}else {
// 其他逻辑
}
}
}
策略模式就是要干掉上面的一坨if-else,使得代码看起来优雅且高大上。
现在就让我们开始干掉这一坨if-else。先总览下结构:
1.首先定义一个OrderHandler接口,此接口规定了处理订单的方法。
public interface OrderHandler {
void handle(Order order);
}
2.定义一个OrderHandlerType注解,来表示某个类是用来处理何种来源的订单。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Service
public @interface OrderHandlerType {
String source();
}
3.接下来就是实现pc端和移动端订单处理各自的handler,并加上我们所定义的OrderHandlerType注解。
@OrderHandlerType(source = "mobile")
public class MobileOrderHandler implements OrderHandler {
@Override
public void handle(Order order) {
System.out.println("处理移动端订单");
}
}
@OrderHandlerType(source = "pc")
public class PCOrderHandler implements OrderHandler {
@Override
public void handle(Order order) {
System.out.println("处理PC端订单");
}
}
4.以上准备就绪后,就是向spring容器中注入各种订单处理的handler,并在OrderService.orderService方法中,通过策略(订单来源)去决定选择哪一个OrderHandler去处理订单。我们可以这样做:
@Service
public class OrderService {