我的方法中包含1个长时间运行的进程,它适用于以下两种不同类型:
代码:
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的过程,无论其内部进行了什么操作。
我对在基本抽象类中移动版本感到困惑,因为这可能会使它与长时间运行的过程紧密相关。我想以一种明天设计的方式,如果我考虑删除版本控制,那么它就不会妨碍我的当前版本设计和代码。
有人可以帮我吗?
答案 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
逻辑作为构造函数参数传递。