美文网首页
DDD实战篇 - 消息触达域的实现

DDD实战篇 - 消息触达域的实现

作者: 小胖学编程 | 来源:发表于2022-12-14 17:20 被阅读0次

    消息触达域是一个通用域。是一个基础组件,通过领域事件的方式将其与业务代码进行解耦。

    在不同的限定上下文中,“用户”有着不同的含义。

    账户域中:用户含义表示的是“账户”;
    消息域中:用户含义表示的是“消息接收人”;

    而消息实体一般有三要素:

    1. 发给谁;
    2. 发什么;(消息内容,也可以是消息事件+填充内容)
    3. 发送渠道;

    消息实体的能力:

    1. 消息send();
    2. 消息频次处理;

    代码实现

    消息实体

    @Data
    public class Message {
    
        /**
         * 消息id
         */
        private String messageId;
    
        /**
         * 消息内容(发什么)
         */
        private MessageContext context;
        /**
         * 消息接收者(发给谁)
         */
        private List<String> allNotifier;
    
        /**
         * 消息渠道(怎么发)
         */
        private ChannelEnum channel;
    
        /**
         * 消息频次控制(触发时机)
         */
        private Predicate<Message> trigger;
    
    
        public void send() {
            CustomApplicationContext.getContext()
                    .publishEvent(new ApplicationNotifyEvent(Lists.newArrayList(this)));
        }
    
        public enum ChannelEnum {
            EMAIL,      //邮件
            SMS;        //短信
        }
    
        @Data
        private static class MessageContext {
            /**
             * 消息事件,选填
             */
            private String event;
            /**
             * 标头,选填
             */
            private Map<String, String> title;
            /**
             * 内容,必填
             */
            private Map<String, String> content;
        }
    
    }
    

    领域事件

    public class ApplicationNotifyEvent extends ApplicationEvent {
    
        private List<Message> messages;
    
        public ApplicationNotifyEvent(List<Message> messages) {
            super(messages);
            this.messages = messages;
            doCheckMessage(messages);
        }
    
        public List<Message> getMessages() {
            return messages;
        }
    
        /**
         * 校验逻辑
         */
        protected void doCheckMessage(List<Message> messages) {
    
        }
    
    }
    

    消息监听者(公共):

    @Slf4j
    @Service
    public class BasicNotifyListener implements ApplicationListener<ApplicationNotifyEvent> {
    
        @Override
        public void onApplicationEvent(ApplicationNotifyEvent event) {
            batchSendMsg(event);
        }
    
    
        protected void batchSendMsg(ApplicationNotifyEvent event) {
            List<Message> messageEntities = event.getMessages();
            if (CollectionUtils.isEmpty(messageEntities)) {
                return;
            }
            messageEntities.forEach(this::sendMessageAsync);
        }
    
        public void sendMessageAsync(Message message) {
            //消息频次触发控制
            if (!Optional.ofNullable(message.getTrigger()).map(r -> r.test(message)).orElse(true)) {
                return;
            }
            //todo 业务处理
        }
    }
    

    工具方法

    @Component
    public class CustomApplicationContext<T extends ApplicationEvent> implements ApplicationContextAware {
    
        private static ApplicationContext context;
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            context = applicationContext;
        }
    
        public static ApplicationContext getContext() {
            return context;
        }
    
    
        public static <T> void publishEventIfNotNull(T event) {
            //兼容消息为null的场景
            if (event == null) {
                return;
            }
            context.publishEvent(event);
        }
    }
    
    

    相关文章

      网友评论

          本文标题:DDD实战篇 - 消息触达域的实现

          本文链接:https://www.haomeiwen.com/subject/brklqdtx.html