模板方法模式简化代码复用代码

需求

平时工作中,我们会有不少地方会使用到模板方法模式。它既可以简化们的代码,也可以规范我们的代码逻辑、约束我们的编码范围。是一个面向接口编程的好例子.

来看看我们的例子,主要场景以网管监控系统补偿数据场景来展开。简单看下spec

1、A系统监控B、C系统,B、C系统分别有BBiz与CBiz的业务

2、B、C系统通过kafka上报配置,状态,告警变更给A系统

3、A系统更新业务数据,并分析告警,状态等通知给平台其它系统

4、步骤2可能出现各种各样的问题,B、C系统可能有问题没有发出消息,A系统可能有问题没有消费消息。每天A系统会定时与B、C系统对比数据,并以B、C系统数据为准更新A系统数据

依赖设计

代码实现

1、A系统监控B、C系统,B、C系统分别有BBiz与CBiz的业务

public class BBiz {
}
public class CBiz {
}
public class BPo {
}
public class CPo {
}

2、B、C系统通过kafka上报配置,状态,告警变更给A系统

@Component
public class TopicBSubscriber {
    @Autowired
    private AbstractMessageBiz<BBiz, BPo> messageBiz;

    public void onListener(List<Record> list) {
        for (Record r : list) {
            BBiz biz = convert(r);
            messageBiz.update(biz);
        }
    }
}

@Component
public class TopicCSubscriber {
    @Autowired
    private AbstractMessageBiz<CBiz, CPo> messageBiz;

    public void onListener(List<Record> list) {
        for (Record r : list) {
            CBiz biz = convert(r);
            messageBiz.update(biz);
        }
    }
}

3、A系统更新业务数据,并分析告警,状态等通知给平台其它系统

这里使用模板方法模式来处理数据源,并好了存库通知三方系统等一系列操作

/**
 *
 * @param <T> 消息模型
 * @param <D> 数据库模型
 */
public abstract class AbstractMessageBiz<T, D> {
    public void update(T msg) {
        D bizInDb = queryFormDb(msg);
        D bizInMsg = convert(msg);
        updateDb(bizInMsg, bizInDb);
        List<Alarm> alarms = generateAlarms(bizInMsg, bizInDb);
        for (Alarm a : alarms) {
            // 这里可以是一个监听器
            // 1、监听到告警,则发送到告警平台
            // 2、告警本地落库
            // 3、分析告警最高级别,关联到业务上
        }
    }

    protected abstract D convert(T t);

    /**
     * 根据变化的属性
     * @param forUpdate
     * @return
     */
    protected abstract List<Alarm> generateAlarms(D forUpdate, D inDb);

    /**
     * 从数据库查相关消息
     *
     * @param t 消息
     * @return 数据库模型
     */
    protected abstract D queryFormDb(T t);

    /**
     * 存库
     * @param bizInMsg
     * @param d 业务
     */
    protected abstract void updateDb(D bizInMsg, D d);
}

public class BBizConsumer extends AbstractMessageBiz<BBiz, BPo> {
}
public class CBizConsumer extends AbstractMessageBiz<CBiz, CPo> {
}

4、定时check

主要是这个private List<AbstractBizCheck<?, ?>> bizCheckers;可以直接依赖。

这里C没有实现BizCheck功能,即不需要对数据进行补偿。

如果后续需要对C进行check功能,仅需要新增文件

public class CBizChecker extends AbstractBizCheck<CBiz, CPo> 即可

@Component
public class CheckJob {
    @Autowired
    private List<AbstractBizCheck<?, ?>> bizCheckers;

    /**
     * 定时任务调用
     */
    public void onCheck() {
        for (AbstractBizCheck<?, ?> checker : bizCheckers) {
            checker.check();
        }
    }
}

public abstract class AbstractBizCheck<T, D> {
    @Autowired
    AbstractMessageBiz<T, D> messageBiz;

    public void check() {
        List<T> ts = queryAll();
        for (T t : ts) {
            messageBiz.update(t);
        }
    }

    protected abstract List<T> queryAll();
}

@Component
public class BBizChecker extends AbstractBizCheck<BBiz, BPo> {
    @Override
    List<BBiz> queryAll() {
        return new ArrayList<>();
    }
}

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值