一. 22种代码中的坏味道
二. 有这么一个业务需求
三. 六大设计原则
四. 学习Spring框架的做法
Spring启动后,会执行内部一系列的操作。我们也经常会定义在Spring启动之后,执行一些特定的业务代码。为什么我们不需要改动Spring的源码就能实现功能扩展呢?
package com.hong.start;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
/**
* Created by John on 2019/1/25.
* 项目启动后需要初始化资源
*/
@Component
public class StartupListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
// 防止启动两次
// if (event.getApplicationContext().getParent() != null){
// 启动Spring容器后执行一些代码
System.out.println("服务启动完成,开始初始化资源1。。。");
// }
}
}
五. 使用观察者模式改造优化上面的代码
- 什么是观察者模式?
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private ApplicationContext applicationContext;
/**
* 场景:
* 创建订单,并发送短信通知
* 传统设计:在创建订单的接口中完成订单创建后再发送短信通知,改进点的设计可以把短信通知做成异步的
* 根据单一职责原则,该接口值负责创建订单,至于短信通知(如果扩展的话后面可能添加邮件通知,微信通知等)
* 这时可以使用Spring的事件监听机制在订单创建完成后自动发送短信
*
* @return
*/
@RequestMapping("/createOrder")
public String createOrder() {
System.out.println("订单创建成功。。。");
String orderId = "123";
/**
* 生产者 --》 事件 --》传播 --》监听者
*/
//利用Spring的事件发布订阅(pub/sub)机制实现观察者模式
OrderCreateEvent orderCreateEvent = new OrderCreateEvent(orderId);
applicationContext.publishEvent(orderCreateEvent);
/**
* 不用再下面写短信发送的代码啦,直接弄个监听器
*/
return "OK";
}
}
package com.hong.event;
import org.springframework.context.ApplicationEvent;
/**
* Created by John on 2019/1/25.
* 订单创建事件
*/
public class OrderCreateEvent extends ApplicationEvent{
public OrderCreateEvent(Object source) {
super(source);
}
}
package com.hong.listener;
import com.hong.event.OrderCreateEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
/**
* Created by John on 2019/1/25.
* 订单创建,发送短信监听器
*/
@Component
public class OrderCreateSmsListener implements ApplicationListener<OrderCreateEvent>{
@Override
public void onApplicationEvent(OrderCreateEvent orderCreateEvent) {
//取出订单id
Object orderId = orderCreateEvent.getSource();
System.out.println("调用短信发送接口,完成订单[" + orderId + "]通知");
}
}
六. Spring中的其他设计模式
-
模板方法模式
-
其实也可把上面的做法看成是一种策略模式
七. 小结 -
设计模式应用的两个步骤:
-
根据设计原则衡量代码的好坏
-
选择合适的设计模式,对代码进行设计
-
设计模式的学习建议
-
代码设计时,参考开源框架中类似的实现
-
根据框架内部源码的命名,匹配到对应的设计模式
-
利用拆分关键字的方式,学会分析设计模式的定义
-
多写,多看,多想
-
不为“模式”而用设计模式,于不知不觉中应用