在业务逻辑中,经常会出现分支的情况,于是你会发现下面的代码:
if(conditionA)
{
DoA();
}
else if(conditionB)
{
DoB();
}
else if(...)
{
...
}
else
{
DoCry();
}
这样的代码表面看似很调理,而且condition不能swichcase,所以没办法只能IFELSE,也符合情理。但是大家都知道,IFELSE是有弊端的:
1.可读性差。
2.不方便检查分支是否充分,或有没有拉掉某些分支,即容易产生很难挑出的深层bug。
3.如果添加了分支,需要在业务中修改代码,不能集中配置。
鉴于此,我们应该尽量避免编写这样的分支代码。
那么怎样重构优化这样的代码呢?其实很简单,我们可使用配置表的方式来重构这段代码:
首先我们实例化一个分支和执行方法的映射表:
Dictinary<Condition,Action> configTable=new Dictinary<Condition,Action>();
然后,把所有的【分支-方法】映射添加到映射表中:
configTable.Add(conditionA,DoA);
configTable.Add(conditionB,DoB);
...
configTable.Add(conditionSmile,DoSmile);
在业务逻辑执行时只需要如下调用就可以了:
configTable[condition]();
通过配置表,我们可以让代码更清晰,方便统一检查所有分支而不漏。但明眼人都看出来了,我们还是要修改代码,虽然修改的地方可以集中在一个非业务代码的地方。而代码设计的至高点是大名鼎鼎对【修改关闭,对扩展开发】。那我们有木有办法做到这点呢?答案是呵呵~~肯定必须已经当然的。
废话不多说,怎么做到:
1.写配置文件(在此不做解释,也不推荐,ifelse分支多了去了,都写配置文件会死人的)
2.统一分支业务接口,自动加载分支业务接口的所有实现类到配置表。
代码如下:
定义分支业务接口:
public interface ISwitchBusiness{ string Case{get;} voidDoWork(); }
实现各个分支业务:
public class CaseABusiness: ISwitchBusiness{
public stringCase{get{return "A"; }}
public void DoWork(){ ...}
}
public class CaseBBusiness: ISwitchBusiness{
public stringCase{get{return "B"; }}
public void DoWork(){ ...}
}
...
public class CaseHappyBusiness: ISwitchBusiness{
public string Case{get{return "Happy"; }}
public voidDoWork(){ ...}
}
自动注册各个业务分支到配置表:
var configTable=new Dictinary<string, ISwitchBusiness>();
var regableType= typeof(ISwitchBusiness);
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
foreach (var t inassembly.DefinedTypes){
if (t.IsClass &®ableType.IsAssignableFrom(t))
{
var _case= Activator.CreateInstance(t) as ISwitchBusiness;
configTable.Add(_case.Case,_case);
}
}
在业务逻辑执行时只需要如下调用就可以了:
configTable[condition]. DoWork();