设计模式之责任链应用

将能够处理同一类请求的对象连成一条链,使这些对象都有机会处理请求,所提交的请求沿着链传递。从而避免请求的
发送者和接受者之间的耦合关系。链上的对象逐个判断是否有能力处理该请求,如果能则就处理,如果不能,则传给链上的下一个对象。直到有一个对象处理它为止。

设计模式的应用

设计模式在架构设计中用的恰当,能起到画龙点睛的作用,但如果用的不恰当,反而成为叶公好龙,在后续维护中增加成本,并且没有收益,因此设计模式的引入需要我们好好掂量掂量!

应用场景

以前的一个项目中,大致场景如下:我们需要对装修中的建筑模型进行拆分,并且按照拆分的零件以及一系列规则按照顺序进行排序,并输出为工人可以按时间进行施工的工作,规则是需要根据任务、工作面、工人资源、工种工序要求等一系列条件进行限制和制约,使得保持一个工作面上最好有一个任务持续进行。
在这里插入图片描述

设计

根据调度前期需求调研,此处变化集频繁和变更与一身,因此,此处选择职责链模式和工作流引擎模式解决该需求的设计。职责链模式集中设计各个类要加工的素材,加工后交付给下一个职责类进行处理,无需关心下一个职责类是谁;职责链整体组装依赖外部调用者,外部调用者决定采用哪几个职责类,什么顺序进行组装,以方便需求变更后的处理,而无需影响下一个功能点。流程引擎封装调度状态的变迁,状态需求的变更不再依赖单纯的编程代码,而仅需要更改流程图即可。这里着重介绍下职责链的设计,工作流设计后续有时间再写文章。

职责类均继承自BaseResponsibility抽象基类,抽象类实现了职责链的组装,职责链的执行、职责链的链式调用、职责链共有信息的传递等功能。继承的职责类只需要完成相应的功能即可。DispatchBootstrap职责类完成了所有数据的加载工作;TaskGlobalFilter职责类完成任务的过滤工作;WorkGroupStat完成工作组的效率等的统计工作;WorkGlobalFilter职责类完成工作组的过滤工作;WorkGroupWeightCalc职责类完成每个任务下各个小组的权重计算工作;AssignTaskCore职责类完成指派工作的工作;BizDataCleaning职责类完成业务数据的清理工作;GenerateTaskOrder职责类完成任务单下发,短信发送等一系列工作。
在这里插入图片描述

基类代码

基类是一个抽象类,需要继承实现。

/// <summary>
    /// 职责类基类 ,可参考职责设计模式
    /// 所有的职责类均继承该类,职责类可设置下一个需要处理的职责类
    /// 在职责类调用时,只需调用 ExecuteTask 方法即可
    /// </summary>
    public abstract class BaseResponsibility
    {
        protected OperateInfo _oInfo;
        protected BaseResponsibility responsibility;
        protected ILogger Log = LogManager.GetLogger("biz");

        /// <summary>
        /// 执行关联数据
        /// </summary>
        public ProcessContext Context { get; set; }
        public BaseResponsibility GetResponsibility()
        {
            return responsibility;
        }

        /// <summary>
        /// 设置接下来的职责类,这样就形成了一个职责链,
        /// 职责类被调用后,会沿职责链依次调用
        /// </summary>
        /// <param name="responsibility"></param>
        /// <returns></returns>
        public BaseResponsibility SetResponsibility(BaseResponsibility responsibility)
        {
            this.responsibility = responsibility;

            return this.responsibility;
        }

        /// <summary>
        /// 子类需要实现的处理方法
        /// </summary>
        /// <returns></returns>
        protected abstract void Execute();

        /// <summary>
        /// 执行工序资源的处理
        /// </summary>
        /// <param name="context"></param>
        /// <param name="provider"></param>
        /// <param name="oInfo"></param>
        /// <returns></returns>
        public ProcessContext ExecuteProcess(ProcessContext context, OperateInfo oInfo)
        {
            _oInfo = oInfo;
            Context = context;
            try
            {
                Execute();
            }
            catch (Exception e)
            {
                Trace.WriteLine(string.Format("{0}执行异常,已跳过!{1}", this.GetType().Name, e.Message));
                if (Log != null)
                {
                    Log.Error(this.GetType().Name + " 执行失败,", e);
                }
            }
            if (this.responsibility != null)
            {
                return this.responsibility.ExecuteProcess(Context, oInfo);
            }
            else
            {
                return Context;
            }
        }
    }

上下文

上下文是职责链需要传递的内容,定义如下:

/// <summary>
    /// 工序上下文
    /// </summary>
    public class ProcessContext
    {
        /// <summary>
        /// 工序全局(参数)信息
        /// </summary>
        public ProcessBootInfo ProcessBootInfo { get; set; }


        public ProcessInfo ProcessInfo { get; set; }

        /// <summary>
        /// 项目ID
        /// </summary>
        public int ProjectId { get; set; }

        /// <summary>
        /// 分项ID
        /// </summary>
        public int SubProjectId { get; set; }

        /// <summary>
        /// 公司ID
        /// </summary>
        public int CompanyId { get; set; }

        /// <summary>
        /// 项目结构EpsCode
        /// </summary>
        public string EpsCode { get; set; }

        /// <summary>
        /// skp拆分模型产生的数据
        /// </summary>
        public List<PmSKPTasktInfo> DsSkpTask { get; set; }

        /// <summary>
        /// 中间信息
        /// </summary>
        public Dictionary<string, object> BagInfo { get; set; }

        /// <summary>
        /// 任务执行结果
        /// </summary>
        public ProcessResult ProcessResult { get; set; }

        /// <summary>
        /// 公司Code
        /// </summary>
        public string CompanyCode { get; set; }
    }

结语

链的好处是可以自由组合,每个链和其他均为松耦合。唯一的处理数据来源于上下文。因此链的开发也可以划分为多个开发者进行。调用者就比较简单了,组装链即可。


在此我向大家推荐一个微服务架构学习交流群。交流学习QQ群号:864759589 里面会分享一些资深架构师录制的视频录像:高并发、高性能、分布式、微服务架构的原理,分布式架构等这些成为架构师必备的知识体系。
在这里插入图片描述


引用链接

  1. 口袋代码仓库
  2. 在线计算器
  3. 本节源码:github

猜你喜欢

转载自blog.csdn.net/webmote/article/details/85257100