想想
有一个需求,新用户注册赠送10元券的功能。我们会怎么去实现?
- 用户注册
public class UserService {
// 用户注册
public void register(User user){
// ......
System.out.println("用户注册完成");
}
}
- 活动赠送
public class ActivityService {
// 赠送活动券
public void giveTicket(String userId){
System.out.println(userId+"10元活动券");
}
}
我们会怎么去实现?
- 注册完成直接调用赠送活动券的业务代码
public class UserService {
private ActivityService activityService;
public UserService(ActivityService activityService) {
this.activityService = activityService;
}
// 用户注册
public void register(User user){
// ......
System.out.println("用户注册完成");
activityService.giveTicket(user.getUserId());
}
}
优点:
- 简单容易实现
- 方便做事务回滚
缺点:
-
代码冗余不具有可扩展性
-
高耦合
- 使用AOP从切面完成赠送逻辑
@Aspect
@Service
public class ActivityAop {
private ActivityService activityService;
public ActivityAop(ActivityService activityService) {
this.activityService = activityService;
}
@Pointcut("execution(public * cn.cy.service.UserService.register(..))")
public void userPoint(){
}
@AfterThrowing(pointcut = "userPoint()")
public void ticketHandler(JoinPoint point){
Object[] args = point.getArgs();
// .......
User user = (User)args[0];
activityService.giveTicket(user.getUserId());
}
// ......
}
优点:
- 解耦可扩展
缺点:
-
代码复杂不易编写
-
对事务回滚不方便
-
感觉不是很可靠
- 使用Spring的观察者模式,观察用户注册动作并通知事件处理器进行处理
public class UserService {
private UserPublisher publisher;
public UserService(UserPublisher publisher) {
this.publisher = publisher;
}
// 用户注册
public void register(User user){
// ......
System.out.println("用户注册完成");
// 推送注册消息
publisher.publisherEvent(new UserEvent(user));
}
}
优缺点:
- 跟AOP方式差不多,但是代码比AOP方式清晰好理解,逻辑层次清晰,但是只能单体应用,不便于实现微服务的功能拆分。
- 使用中间件推送注册信息,例如RabbitMQ,将用户信息推送到消息队列
public class UserService {
private RabbitMessage message;
public UserService(RabbitMessage message) {
this.message = message;
}
// 用户注册
public void register(User user){
// ......
System.out.println("用户注册完成");
// 推送注册消息到队列
message.publisher(user);
}
}
优点:
-
完全解耦,将信息发送到中间件服务,通过监听中间服务队列来实现发券
-
好扩展,AOP和观察者模式也一样,可以扩展出跟注册业务相关的其它需求
缺点:
- 除了事务的实现比较麻烦以外,推荐使用这种方式。未考虑到缺点,望交流。
总结
在设计用户注册活动,设备故障消息通知等这类以某一个业务功能点为前提的需求功能,可以将这类业务的信息以消息的形式推送出去以便于后期的功能拓展,降低代码的冗余和耦合。
公众号