都在使用的《模版模式》

模版符合开闭原则,到处用于钩子方法。有的钩子方法不会改变行为,有的钩子会改变运行轨迹。框架中到处使用。
image
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 订阅者
     */
    @Override
    public void addSubscriber(SafetySubscriber subscriber) {
        if (subscribers.contains(subscriber)) {
            return;
        }else {
            subscribers.add(subscriber);
        }

    }

    /**
     * 删除订阅者
     *
     * @param subscriber 订阅者
     */
    @Override
    public 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}
     */
    @Override
    public ChannelEnum getChannelDescription() {
        return ChannelEnum.ORDER_ACTIVATE;
    }
}


posted @ 2024-12-17 18:39  Eular  阅读(22)  评论(0编辑  收藏  举报