说明:
根据实际工作时遇到的需求,需要将实际项目中的很多if…else…的判断进行替代,提高代码的可维护性和可扩展性。我在网上找了一些方法,结合实际的编写以后在本文中总结归纳。主要目的是记录以便之后使用可以参考,网友如有需要也可借鉴学习。
这个是我参考的博客的地址: https://www.cnblogs.com/houzheng/p/10911462.html#_labelTop
开发工具:IDEA、JDK:1.8、MySQL:8.0.13
1.搭建框架
基本框架搭建,参考我上篇博客:https://blog.csdn.net/weixin_43955583/article/details/89742247
3.创建实体类、服务层、控制层
这几个类在第一步的框架搭建时就已经创建了,这里方便起见再写一边,具体内容有差别,但是实现功能不变。
实体类Order:
public class Order {
private String id;
private String name;
private Integer type;
public static Order build(){
return new Order();
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
service:
@Repository
public interface OrderService {
void handleOrder(Order order);
}
service实现类:
@Component
public class OrderServiceImpl implements OrderService {
@Autowired
HandlerOrderContext handlerOrderContext;
@Override
public void handleOrder(Order order) {
//使用策略处理订单
OrderStrategy orderStrategy = handlerOrderContext.getOrderStrategy(order.getType());
orderStrategy.handleOrder(order);
}
}
控制层controller:
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
OrderService orderService;
@GetMapping("/handler/{type}")
public void handleOrder(@PathVariable Integer type){
Order order = Order.build()
.add("id", 1)
.add("name", "免费订单")
.add("type", type);
orderService.handleOrder(order);
}
}
4.核心功能实现
主要时实现策略的逻辑层
/**
* 根据订单类型返回对应的处理策略
*/
@Component
public class HandlerOrderContext {
@Autowired
private ApplicationContext applicationContext;
//存放所有策略类Bean的map
public static Map> orderStrategyBeanMap= new HashMap<>();
public OrderStrategy getOrderStrategy(Integer type){
Class strategyClass = orderStrategyBeanMap.get(type);
if(strategyClass==null) throw new IllegalArgumentException("没有对应的订单类型");
//从容器中获取对应的策略Bean
return applicationContext.getBean(strategyClass);
}
}
/**
* 策略核心功能,获取所有策略注解的类型
* 并将对应的class初始化到HandlerOrderContext中
*/
@Component
public class HandlerOrderProcessor implements ApplicationContextAware {
/**
* 获取所有的策略Beanclass 加入HandlerOrderContext属性中
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
//获取所有策略注解的Bean
Map orderStrategyMap = applicationContext.getBeansWithAnnotation(HandlerOrderType.class);
orderStrategyMap.forEach((k,v)->{
Class orderStrategyClass = (Class) v.getClass();
int type = orderStrategyClass.getAnnotation(HandlerOrderType.class).value();
//将class加入map中,type作为key
HandlerOrderContext.orderStrategyBeanMap.put(type,orderStrategyClass);
});
}
}
5.自定义策略注解
@Target(ElementType.TYPE) //作用在类上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited //子类可以继承此注解
public @interface HandlerOrderType {
/**
* 策略类型
* @return
*/
int value();
}
6.策略接口和实现
/**
* 处理订单策略
*/
public interface OrderStrategy {
void handleOrder(Order order);
}
@Component
@HandlerOrderType(Order.FREE) //使用注解标明策略类型
public class FreeOrderStrategy implements OrderStrategy {
@Override
public void handleOrder(Order order) {
System.out.println("----处理免费订单----");
}
}
@Component
@HandlerOrderType(Order.HALF)
public class HalfOrderStrategy implements OrderStrategy {
@Override
public void handleOrder(Order order) {
System.out.println("----处理半价订单----");
}
}
@Component
@HandlerOrderType(Order.DISCOUT)
public class DiscoutOrderStrategy implements OrderStrategy {
@Override
public void handleOrder(Order order) {
System.out.println("----处理打折订单----");
}
}
完成。
启动项目,在浏览器中输入地址http://localhost:8080/order/handler/{type},type处分别输入1,2,3,能够在控制台输出
成功