模版符合开闭原则,到处用于钩子方法。有的钩子方法不会改变行为,有的钩子会改变运行轨迹。框架中到处使用。
Channel中定义了需要的操作,AbstractChannel实现了核心功能,然后不同的Channel实现只需要告知具体channel的描述信息即可。
Channel 接口⬇︎⬇︎⬇︎
点击查看代码
package com.xxx.sales.subscription.service.pubsub;import com.xxx.sales.subscription.service.pubsub.dto.SubscribersResult;
import com.xxx.sales.subscription.service.pubsub.enums.ChannelEnum;/*** 通道/频道* <pre>* 消息发送到指定的channel中, 各个订阅者监听channel* </pre>** @author huhaiyang*/
public interface Channel<K, V extends SubscribersResult> {/*** 获得信道描述** @return {@link ChannelEnum}*/ChannelEnum getChannelDescription();/*** 添加订阅者** @param subscriber 订阅者*/void addSubscriber(SafetySubscriber<K, V> subscriber);/*** 删除订阅者** @param subscriber 订阅者*/void removeSubscriber(SafetySubscriber<K, V> subscriber);}
AbstractChannel 实现重要功能⬇︎⬇︎⬇︎
点击查看代码
package com.xxx.sales.subscription.service.pubsub.chanels;import com.xxx.sales.subscription.service.pubsub.Channel;
import com.xxx.sales.subscription.service.pubsub.SafetySubscriber;
import com.xxx.sales.subscription.service.pubsub.dto.SubscriberResult;
import com.xxx.sales.subscription.service.pubsub.dto.SubscribersResult;
import lombok.extern.slf4j.Slf4j;import java.util.LinkedList;/**** @author huhaiyang*/
@Slf4j
public abstract class AbstractChannel<K, V extends SubscribersResult> implements Channel<K, V> {private LinkedList<SafetySubscriber<K, V>> subscribers = new LinkedList<>();/*** 添加订阅者** @param subscriber 订阅者*/@Overridepublic void addSubscriber(SafetySubscriber subscriber) {if (subscribers.contains(subscriber)) {return;}else {subscribers.add(subscriber);}}/*** 删除订阅者** @param subscriber 订阅者*/@Overridepublic void removeSubscriber(SafetySubscriber subscriber) {subscribers.remove(subscriber);}/*** 接收消息** @param message 消息* @param collectResult 收集结果*/public void receiveMessage(K message,V collectResult){log.info("receiveMessage start...");for (SafetySubscriber<K, V> subscriber : subscribers) {subscriber.update(message, collectResult);SubscriberResult resultBySubscriber = collectResult.getResultBySubscriber(subscriber);if (!resultBySubscriber.isSuccess()) {log.info("{}执行失败,开始失败策略...",subscriber.getClass().getSimpleName());subscriber.failBack(message,collectResult);log.info("{}失败策略执行结束.",subscriber.getClass().getSimpleName());}}log.info("receiveMessage end...");}
}
OrderActivateChannel 订单激活channel ⬇︎⬇︎⬇︎
点击查看代码
package com.xxx.sales.subscription.service.pubsub.chanels;import com.xxx.sales.subscription.service.pubsub.dto.OrderActivateMessage;
import com.xxx.sales.subscription.service.pubsub.dto.SubscribersResult;
import com.xxx.sales.subscription.service.pubsub.enums.ChannelEnum;
import org.springframework.stereotype.Component;/*** 订单激活的channel** @author huhaiyang* @date 2022 2022/12/8*/
@Component
public class OrderActivateChannel extends AbstractChannel<OrderActivateMessage, SubscribersResult> {/*** 获得信道描述** @return {@link ChannelEnum}*/@Overridepublic ChannelEnum getChannelDescription() {return ChannelEnum.ORDER_ACTIVATE;}
}