声明: 此文章仅限于记录学习之用 , 受限于自身水平和理解能力 , 因此结论可能是不正确的. 如果您需要学习,建议参考其他文章
打个比方 你骑着电瓶车上班, 走到路口红灯亮了, 大家都抬着头看那圆圆的猴屁股啥时候变绿. 只要变绿,必须电门拧到底,率先冲出线,才有可能不迟到~~
上述例子中观者者是"各位骑士" ,被观察者 “红绿灯”. . 当被观察者发生变化时, 观察者做出相应动作. 这就是观察者模式.
有了上述定义, 代码实现就比较简单了. 定义观察者 和被观察者. 被观察者变化时, 遍历循环被观察者就完事了~
观察者模式一般就是解耦用的, 比如你需要调用发邮件通知啊,向消息队列里推送消息啊. 这些与核心业务关系不大, 又不想破坏service的纯洁性(单一职责). 可以让代码更规范些.
试想一下. 你在orderService中 又引入了 EmailService是不是多多少少有点不合适…
大家了解完观察者模式了, 一般还是很少用, 因为用起来不方便… 我学习设计模式也有这个烦恼, 就是例子与实际差别太大了. 想使用又很麻烦… 经常开发的人都知道,只要遇到开发不科学的问题, spring就一定会有解决方案. . .
下面以用户信用卡扣款成功后, 发送email和短信通知为例.
package com.isimple.portal.model;
/**
* @author Administrator
* @version 1.0
* @description: 邮箱通知
* @date 2024/1/17 16:12
*/
public class Email {
/**
* 邮箱地址
*/
private String address;
public Email(String address) {
this.address = address;
}
public String getAddress() {
return address;
}
}
package com.isimple.portal.model;
/**
* @author Administrator
* @version 1.0
* @description: 短信通知
* @date 2024/1/17 16:12
*/
public class SMS {
private String phoneNumber;
public SMS(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getPhoneNumber() {
return phoneNumber;
}
}
package com.isimple.portal.model;
import org.springframework.core.ResolvableType;
import org.springframework.core.ResolvableTypeProvider;
/**
* @author Administrator
* @version 1.0
* @description: 消息通知
* @date 2024/1/17 16:13
*/
/**
* 注意: implements ResolvableTypeProvider 是为了解决泛型擦除问题.
*/
public class NoticeEvent<T> implements ResolvableTypeProvider {
private T data;
/**
* 通知内容
*/
private String message;
public NoticeEvent(T data, String message) {
this.data = data;
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public String getMessage() {
return message;
}
/**
* 重写此方法解决泛型擦除问题
* @return
*/
@Override
public ResolvableType getResolvableType() {
return ResolvableType.forClassWithGenerics(getClass(), ResolvableType.forInstance(getData()));
}
}
package com.isimple.portal.model;
import org.springframework.core.ResolvableType;
import org.springframework.core.ResolvableTypeProvider;
/**
* @author Administrator
* @version 1.0
* @description: 消息通知
* @date 2024/1/17 16:13
*/
/**
* 注意: implements ResolvableTypeProvider 是为了解决泛型擦除问题.
*/
public class NoticeEvent<T> implements ResolvableTypeProvider {
private T data;
/**
* 通知内容
*/
private String message;
public NoticeEvent(T data, String message) {
this.data = data;
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public String getMessage() {
return message;
}
/**
* 重写此方法解决泛型擦除问题
* @return
*/
@Override
public ResolvableType getResolvableType() {
return ResolvableType.forClassWithGenerics(getClass(), ResolvableType.forInstance(getData()));
}
}
package com.isimple.portal.service.impl;
import com.isimple.portal.model.Email;
import com.isimple.portal.model.NoticeEvent;
import com.isimple.portal.model.SMS;
import com.isimple.portal.service.EventDemoService;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* @author Administrator
* @version 1.0
* @description:
* @date 2024/1/22 11:08
*/
@Service
public class EventDemoServiceImpl implements EventDemoService {
@Resource
private ApplicationContext applicationContext;
@Override
public String notice(String code) {
String message = "[工业银行]尊敬的吴老二,你好,本次消费1000.00元,余额0元";
if ("sms".equals(code)) {
applicationContext.publishEvent(new NoticeEvent<SMS>(new SMS("13800138000"), message));
}
if ("email".equals(code)) {
applicationContext.publishEvent(new NoticeEvent<Email>(new Email("[email protected]"), message));
}
return "success";
}
}
这样做完, 事件监听就已经和业务代码解耦了, 也可以进一步整理,比如 建立"event"包. 把所有的事件监听规整起来.这样代码相对整洁一些~
https://juejin.cn/post/7323793129710551080