nblfeng

virtual
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

职责链模式在业务流程开发中的应用

Posted on 2008-12-25 08:32  nblfeng  阅读(3629)  评论(20编辑  收藏  举报

  做过OA的朋友都知道,整个项目中最为核心的内容就是业务流程.去年在学校的时候,偶有幸也参与了一家规划院OA项目的开发^_^ ,至今,项目已基本结束,偶也从团队中出来另寻了一份工作.后来,在前任老板的请求下,也帮忙做了一段时间的维护工作,也就在那时,许多细小的问题一一浮现出来了~~~~

  先来介绍下该OA项目中的业务流程吧,其主要包括了三大流程:建筑流程,市政流程,规划流程.每个流程中包括了多道业务工序.比如建筑流程,工序如下:

  对于后期维护时候碰到的问题,比如:某道工序中加入一些内容;"建筑质量评定"工序结束后,结算工日等.这些还比较容易解决的,可碰到流程的修改(走向)问题时,那就是一个大工程了,因为当时开发这个项目的时候,都是采用面向过程的思想来解决问题的,因此在维护上要花费很大的功夫.上图上也可以看到,其中几条"特别"的箭头("组织项目组人员"工序),是在后期新增的,那时确实是个噩梦:从一大堆代码中找寻"组织项目组人员"工序处理的功能块,然后进行分支的判断.....(还是让我重新做个项目吧~~~~)

  后来,在现任主管的帮助下,参与了一系列大小不一的项目,同时也强迫我们采用面向对象的思想来解决问题(无论多小的问题),至今,算是有一个脚踏入了面向对象这个门槛吧,o(∩_∩)o

  一天突发奇想,似乎可以将职责链模式应用到业务流程的开发上来,于是说干就干,写了一个Demo来证实自己的想法,同时也算是对曾经的OA项目做个总结吧,虽然比较晚,^_^

  正文开始......

  该Demo将实现处理一个简单的业务流程,该流程由下列几道工序组成:项目承接,项目校对,项目评审,项目结算;各个工序间的关系如下:
       ↗ 项目校对 ↘
  项目承接    ↓  项目结算
       ↘ 项目评审 ↗

  可以看出,这个业务流程的走向有3种方式:

    1、项目承接 → 项目校对 → 项目结算
    2、项目承接 → 项目评审 → 项目结算
    3、项目承接 → 项目校对 → 项目评审 → 项目结算

  同时,我希望各个工序间的关系(流程走向)可以方便的进行转换,或是在原先的流程基础上加入新的工序、删除工序(任意位置).

  设计类图,比较简单.....

  差不多可以开始代码实现了......

  命名空间:BLL

  1、基类WordProcedure.cs
  (1).定义变量
   /// <summary>
        /// 下一工序集
        /// </summary>
        protected List<WorkProcedure> NextProcedureList;
  (2).定义属性
   protected string name;
        /// <summary>
        /// 获取工序名称【只读】
        /// </summary>
        public string Name
        {
            get { return name; }
        }
  (3).构造函数
   /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="Name">业务流程名称</param>
        public WorkProcedure(string Name)
        {
            this.name = Name;

            this.NextProcedureList = new List<WorkProcedure>();
        }

  (4).公共方法
   /// <summary>
        /// 添加下一道工序
        /// 如果存在多个下一道工序,则重复调用该方法即可
        /// </summary>
        /// <param name="NextProcedure"></param>
        public void AddNextProcedure(WorkProcedure NextProcedure)
        {
            this.NextProcedureList.Add(NextProcedure);
        }

        /// <summary>
        /// 移除下一道工序
        /// </summary>
        /// <param name="NextProcedure"></param>
        public void RemoveNextProcedure(WorkProcedure NextProcedure)
        {
            if (this.NextProcedureList.Contains(NextProcedure))
            {
                this.NextProcedureList.Remove(NextProcedure);
            }
        }

        /// <summary>
        /// 是否存在该下一道工序
        /// </summary>
        /// <param name="ProcedureName">工序名称</param>
        /// <returns></returns>
        public int IsExistProcedure(string ProcedureName)
        {
            int index = -1; //不存在
            for (int i = 0; i < this.NextProcedureList.Count; i++)
            {
                if (this.NextProcedureList[i].Name == ProcedureName)
                {
                    index = i;
                    break;
                }
            }
            return index;
        }

        /// <summary>
        /// 处理请求,子类继承后实现各自的方法
        /// </summary>
        /// <param name="Request">请求消息标志</param>
        public abstract void HandleRequest(object Request);

2、子类"项目承接":xiangMCJ.cs
  public class xiangMCJ : WorkProcedure
    {
        public xiangMCJ(string Name) : base(Name) { }

        public override void HandleRequest(object Request)
        {
            if (Request.ToString() == "已开始")
            {
                Console.WriteLine(this.name + Request + ",处理中......");

                this.HandleRequest("已完成");              
            }
            else if (Request.ToString() == "已完成")
            {
                Console.WriteLine(this.name + " 已完成!");

                //提交至"项目校对"
                string procedureName = "项目校对";
                int index = this.IsExistProcedure(procedureName);
                if (index != -1)
                {
                    Console.WriteLine("提交至下一工序:" + this.NextProcedureList[index].Name);
                    this.NextProcedureList[index].HandleRequest("已开始");
                }
                else
                {
                    Console.WriteLine(this.name + " 的下一道工序:" + procedureName + " 不存在!");
                }
            }
        }
    }

   3、子类"项目校对":xiangMJD.cs 和"项目评审":xiangMPS.cs 同上类似

 4、子类"项目结算":xiangMJS.cs
  public class xiangMJS : WorkProcedure
    {
        public xiangMJS(string Name) : base(Name) { }

        public override void HandleRequest(object Request)
        {
            if (Request.ToString() == "已开始")
            {
                Console.WriteLine(this.name + Request + ",处理中......");

                this.HandleRequest("已完成");
            }
            else if(Request.ToString() == "已完成")
            {
                Console.WriteLine(this.name + "已完成,整个项目结束!");
            }
        }
    }

5、客户端调用(客户端为控制台应用程序)
namespace WorkFlowDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            BLL.WorkProcedure xiangMCJ = new BLL.xiangMCJ("项目承接"); //创建工序:项目承接
            BLL.WorkProcedure xiangMJD = new BLL.xiangMJD("项目校对"); //创建工序:项目校对
            BLL.WorkProcedure xiangMPS = new BLL.xiangMPS("项目评审"); //创建工序:项目评审
            BLL.WorkProcedure xiangMJS = new BLL.xiangMJS("项目结算"); //创建工序:项目结算

      //职责链关系:各个工序间的相互关系

            xiangMCJ.AddNextProcedure(xiangMJD); //项目承接的下一道工序:项目校对
            xiangMCJ.AddNextProcedure(xiangMPS); //项目承接的下一道工序:项目评审

            xiangMJD.AddNextProcedure(xiangMPS); //项目校对的下一道工序:项目评审
            xiangMJD.AddNextProcedure(xiangMJS); //项目校对的下一道工序:项目结算

            xiangMPS.AddNextProcedure(xiangMJS); //项目评审的下一道工序:项目结算

            
            //待会在测试时,在这里加入代码......

 

    //业务流程从"项目承接"开始,接下来的请求处理在相应的子类中判断
            string request = "已开始";
            xiangMCJ.HandleRequest(request);

            Console.Read();
        }
    }
}

 

   运行下看看......

  

   如果想改动下流程的走向,使其达到这样的效果:

     ↗ 项目校对
项目承接   ↓   项目结算
    ↘ 项目评审 ↗

   那该如何呢?......

  只要在客户端加入如下代码: xiangMJD.RemoveNextProcedure(xiangMJS); //移除项目校对与项目结算的关系

  

  如果希望在原先流程的基础上,在"项目结算"后加入新的工序"项目归档"........

  那还是同样,在客户端加入:

  BLL.WorkProcedure xiangMGD = new BLL.xiangMCJ("项目归档"); //创建新的工序:"项目归档"

  xiangMJS.AddNextProcedure(xiangMGD); //建立"项目结算"的下一道工序"项目归档"

  不过这样还是不够的,同时还需要修改子类"xiangMJS.cs",因为此时,"项目结算"不是整个流程的结束了.

 

  没有结束的结束......

  原来发现,写博客也是件累人的事,很佩服一些高手们能写出那么多通俗易懂的文章来.看了一篇自己写的,还有很多东西未能表述清楚,比如移除一道工序,转换两道或多道工序等等,未能一一列出.
  写下此篇的目的,在上面也讲到过,一来是为了对曾经的那个OA项目做个总结,找寻业务流程开发中的捷径;二来也为了对自己所学的设计模式做下自我测试;同时也希望博客园中的那么多高手来一起相互讨论下各自在关于业务流程开发中的经验^_^