使步骤与长时间运行的流程保持同步,并为代码替换创建通用层

时间:2019-02-04 08:14:02

标签: c#

我的方法中包含1个长时间运行的进程,它适用于以下两种不同类型:

  • Type1
  • Type2

代码:

public interface IBaseType
    {
        MyResult LongRunningProcess(int noOfTimes); //doenst save long running process data in database.just returns the results to consumer
        void LongRunningProcess(int noOfTimes); //Save results of long running process in database.Background job with on-demand as well as scheduled
    }

public class Type1 : IBaseType
{
    public void LongRunningProcess(int noOfTimes)
        {
           //Step1 : 
           for (int i = 0; i < noOfTimes; i++)
               {
             //Create connection with database.
             //Do some processing based on type1
             //Save results of those processing
            }

        //Step2:
        // Creating versioning here  : If this failed then rollback step1

            //Step3 : if step1 and step2 successfull than mark this job as succeeded else failed
        // Updating time of whole process in table
    }
 }




 public class Type2 : IBaseType
   {
        public void LongRunningProcess(int noOfTimes)
            {
               //Step1 : 
               for (int i = 0; i < noOfTimes; i++)
                   {
                 //Create connection with database.
                 //Do some processing based on type2
                 //Save results of those processing
                }

            //Step2:
            // Creating versioning here  : If this failed then rollback step1

                //Step3 : if step1 and step2 successfull than mark this job as succeeded else failed
            // Updating time of whole process in table
        }
   }

因此您可以在此处看到两种类型的Step2和Step3代码都在重复,因此我想避免两种类型的step2和step3代码重复。

第二,我想使步骤1和步骤2保持同步,以使步骤2失败,然后回滚整个步骤1的过程,无论其内部进行了什么操作。

我对在基本抽象类中移动版本感到困惑,因为这可能会使它与长时间运行的过程紧密相关。我想以一种明天设计的方式,如果我考虑删除版本控制,那么它就不会妨碍我的当前版本设计和代码。

有人可以帮我吗?

2 个答案:

答案 0 :(得分:2)

您可以在此处应用template design pattern

您将拥有一个抽象类,其中包含共享的代码或算法(这两种类型都相同)。并且每种类型都应实现算法的特定部分-处理部分。

abstract class AbstractClass
{
    public abstract void Process();

    // The "Template method"
    public void TemplateMethod()
    {
        for (int i = 0; i < 5; i++)
        {
            //Create connection with database.
            Process();
            //Save results of those processing
        }

    //Step2:
    // Creating versioning here  : If this failed then rollback step1

    //Step3 : if step1 and step2 successfull than mark this job as succeeded else failed
    // Updating time of whole process in table
    }
}

class Type1 : AbstractClass
{
    public override void Process()
    {
       //Do some processing based on type1
    } 
}

class Type2 : AbstractClass
{
    public override void Process()
    {
        //Do some processing based on type2
    }
}  

为了分隔版本控制逻辑,请将逻辑注入到类中,如下所述,在保存到db之前完成版本控制,因此只有成功了,您才真正进行保存。如果不是这种情况,并且您需要在写入db之后进行版本控制,请检查用于写入db的连接器,它应该有某种使用db transactions的方式(允许您提交或回滚)在确认满足约束条件后进行更改)。

抽象类AbstractClass     {         私有只读IVersionInterface _versionCreator;

    protected AbstractClass(IVersionInterface versionCreator)
    {
        _versionCreator = versionCreator;
    }

    public abstract void Process();

    public void TemplateMethod()
    {
        var versionCreated = _versionCreator.CreateVersion();
        if (!versionCreated)
        {
          return;
        }

       for (int i = 0; i < 5; i++)
       {
           //Create connection with database.
           Process();
          //Save results of those processing
      }

      //Step3 : if step1 and step2 successful than mark this job as 
     //succeeded else failed
     // Updating time of whole process in table
    }
}

class Type1 : AbstractClass
{

    public Type1(IVersionInterface versionCreator) : 
base(versionCreator)
    {
    }

    public override void Process()
    {
        //Do some processing based on type1
    }
}

class Type2 : AbstractClass
{

    public Type2(IVersionInterface versionCreator) : 
base(versionCreator)
    {
    }

    public override void Process()
    {
        //Do some processing based on type2
    }
}  

interface IVersionInterface
{
    bool CreateVersion();
}

class VersionCreator : IVersionInterface
{
    //return true or false for success or failure
    public bool CreateVersion()
    {
        //logic here
    }
}

答案 1 :(得分:0)

我将创建一个类来管理以Func作为构造函数参数运行的进程。这样可以灵活使用具有不同参数的函数,并获得不同的结果。

示例:

public class LongProcessRunner<T>
{
    private Func<T> longProcess;

    public LongProcessRunner(Func<T> longProcess)
    {
        this.longProcess = longProcess;
    }

    public T RunAndReturn(int numberOfTimes)
    {
        for (var i = 0; i < numberOfTimes; i++)
        {
            //connect to db
            var processResult = longProcess();
            //Save results
        }

        //versioning & rest 

        //return stuff
        var processRunner = new LongProcessRunner(() => MyFunctionWithoutParameter());

    }
}

因此,您可以使用可能的设置来创建此类:

var processRunner = new LongProcessRunner<MyClass>(() => MyFunctionWithParameter("parameter1", "parameter2"));

var otherProcessRunner = new LongProcessRunner<MyOtherClass>(() => MyFunctionWithoutParameter());

因此,您可以自定义所需的任何内容,还可以将save, connect to db, versioning逻辑作为构造函数参数传递。