设计模式4思考——对于一个简单"流程"的设计思考
最近的学生考试报名项目中遇到这样一个应用场景。系统要实现考生的报名流程。根据考生的身份证进行多个业务逻辑的校验。1、身份证的合法性;2、系统中是否有该考生的信息;3、该考生是否别调整了考试日期;etc.并且这些业务逻辑有先后关系。
在实际应用中遇到的问题是不同省份的报名规则不同,业务逻辑流程不同。于是在系统的配置文件中出现了校验规则的开关项,并在代码中用 if(开关项){} else {} 包围住校验逻辑。一个函数的代码往往有上千行,给修改带来了巨大的麻烦。
用什么方法可以消除这种流程与具体校验方法之间的耦合呢?(因为校验方法之间存在逻辑关系,所以无法使用 Template Method 模式来消除这种耦合)。
于是我设计了如下一个模式来处理这种变化:
class RegInfo:在流程中的实体类,为流程提供判断条件。
class RegCheck:关键为子类定义了 abstract ExecuteCheck() 接口决定流程的下一步,并让子类来实现。
RegCheckIsLegal:RegCheck:封装了流程中具体的业务逻辑,实现了父类的ExecuteCheck()。自己决定流程的下一步。
同上:
RegCheckMgr:流程管理类,它实现了对驱动的驱动。关键是 check() 方法。
客户端:
这个流程管理模式应该是 state 模式的演变。
在实际应用中遇到的问题是不同省份的报名规则不同,业务逻辑流程不同。于是在系统的配置文件中出现了校验规则的开关项,并在代码中用 if(开关项){} else {} 包围住校验逻辑。一个函数的代码往往有上千行,给修改带来了巨大的麻烦。
用什么方法可以消除这种流程与具体校验方法之间的耦合呢?(因为校验方法之间存在逻辑关系,所以无法使用 Template Method 模式来消除这种耦合)。
于是我设计了如下一个模式来处理这种变化:
class RegInfo:在流程中的实体类,为流程提供判断条件。
public class RegInfo
{
private string IDCard;
public bool IsLegal;
public bool IsRepeat;
public bool IsAdjust;
public bool IsAdjustExpire;
public bool IsForbidExpire;
public bool IsAttend;
public bool IsTaskOver;
public RegInfo(string idcard)
{
IsLegal = getBool(idcard.Substring(0, 1));
IsRepeat = getBool(idcard.Substring(1,1));
IsAdjust = getBool(idcard.Substring(2, 1));
IsAdjustExpire = getBool(idcard.Substring(3, 1));
IsForbidExpire = getBool(idcard.Substring(4, 1));
IsAttend = getBool(idcard.Substring(5, 1));
IsTaskOver = getBool(idcard.Substring(6, 1));
}
private bool getBool(string bit)
{
return bit == "1" ? true : false;
}
}
{
private string IDCard;
public bool IsLegal;
public bool IsRepeat;
public bool IsAdjust;
public bool IsAdjustExpire;
public bool IsForbidExpire;
public bool IsAttend;
public bool IsTaskOver;
public RegInfo(string idcard)
{
IsLegal = getBool(idcard.Substring(0, 1));
IsRepeat = getBool(idcard.Substring(1,1));
IsAdjust = getBool(idcard.Substring(2, 1));
IsAdjustExpire = getBool(idcard.Substring(3, 1));
IsForbidExpire = getBool(idcard.Substring(4, 1));
IsAttend = getBool(idcard.Substring(5, 1));
IsTaskOver = getBool(idcard.Substring(6, 1));
}
private bool getBool(string bit)
{
return bit == "1" ? true : false;
}
}
class RegCheck:关键为子类定义了 abstract ExecuteCheck() 接口决定流程的下一步,并让子类来实现。
public abstract class RegCheck
{
public RegCheckMgr Rcm;
public RegInfo ri;
public RegCheck(RegCheckMgr rcm,RegInfo ri)
{
this.Rcm = rcm;
this.ri = ri;
}
public abstract void ExecuteCheck();
}
{
public RegCheckMgr Rcm;
public RegInfo ri;
public RegCheck(RegCheckMgr rcm,RegInfo ri)
{
this.Rcm = rcm;
this.ri = ri;
}
public abstract void ExecuteCheck();
}
RegCheckIsLegal:RegCheck:封装了流程中具体的业务逻辑,实现了父类的ExecuteCheck()。自己决定流程的下一步。
public class RegCheckIsLegal:RegCheck
{
public RegCheckIsLegal(RegCheckMgr rcm, RegInfo ri):base(rcm,ri)
{
}
public override void ExecuteCheck()
{
//throw new NotImplementedException();
if (this.ri.IsLegal)
{
this.Rcm.NextRegCheck = new RegCheckIsRepeat(this.Rcm,this.ri);
}
else
{
this.Rcm.NextRegCheck = null;
this.Rcm.RegCheakResult = false;
}
}
}
{
public RegCheckIsLegal(RegCheckMgr rcm, RegInfo ri):base(rcm,ri)
{
}
public override void ExecuteCheck()
{
//throw new NotImplementedException();
if (this.ri.IsLegal)
{
this.Rcm.NextRegCheck = new RegCheckIsRepeat(this.Rcm,this.ri);
}
else
{
this.Rcm.NextRegCheck = null;
this.Rcm.RegCheakResult = false;
}
}
}
同上:
public class RegCheckIsAdjust:RegCheck
{
public RegCheckIsAdjust(RegCheckMgr rcm, RegInfo ri): base(rcm, ri)
{
}
public override void ExecuteCheck()
{
//throw new NotImplementedException();
if (this.ri.IsAdjust)
{
this.Rcm.NextRegCheck = null;
this.Rcm.RegCheakResult = false;
}
else
{
this.Rcm.NextRegCheck = null;
this.Rcm.RegCheakResult = true;
}
}
}
{
public RegCheckIsAdjust(RegCheckMgr rcm, RegInfo ri): base(rcm, ri)
{
}
public override void ExecuteCheck()
{
//throw new NotImplementedException();
if (this.ri.IsAdjust)
{
this.Rcm.NextRegCheck = null;
this.Rcm.RegCheakResult = false;
}
else
{
this.Rcm.NextRegCheck = null;
this.Rcm.RegCheakResult = true;
}
}
}
RegCheckMgr:流程管理类,它实现了对驱动的驱动。关键是 check() 方法。
public class RegCheckMgr
{
public RegCheck NextRegCheck;
public bool RegCheakResult;
public RegCheckMgr(RegInfo ri)
{
this.NextRegCheck = new RegCheckIsLegal(this, ri);
}
public RegCheckMgr(RegCheck rc)
{
NextRegCheck = rc;
}
public string check()
{
do
{
NextRegCheck.ExecuteCheck();
} while (NextRegCheck != null);
return RegCheakResult.ToString();
}
}
{
public RegCheck NextRegCheck;
public bool RegCheakResult;
public RegCheckMgr(RegInfo ri)
{
this.NextRegCheck = new RegCheckIsLegal(this, ri);
}
public RegCheckMgr(RegCheck rc)
{
NextRegCheck = rc;
}
public string check()
{
do
{
NextRegCheck.ExecuteCheck();
} while (NextRegCheck != null);
return RegCheakResult.ToString();
}
}
客户端:
protected void btn1_Click(object sender, EventArgs e)
{
RegInfo ri = new RegInfo(this.txt1.Text.Trim());
RegCheckMgr rcm = new RegCheckMgr(ri);
this.lbl1.Text = "result-print:" + rcm.check();
}
{
RegInfo ri = new RegInfo(this.txt1.Text.Trim());
RegCheckMgr rcm = new RegCheckMgr(ri);
this.lbl1.Text = "result-print:" + rcm.check();
}
这个流程管理模式应该是 state 模式的演变。