代码重构中发现的设计模式的运用
前天写好了表单映射这一块的demo版,这两天作代码的重构,发现了一点有意思的事。
private string RelateExpr(string parent)
{
for(int i=0;i<this.MappingList.Count;i++)
{
MappingItem item = (MappingItem)this.MappingList[i];
if(item.DesNode.StartsWith(parent))
{
return item.Expr;
}
}
return "";
}
private string SearchExpr(string destinationNode)
{
for(int i=0;i<this.MappingList.Count;i++)
{
MappingItem item = (MappingItem)this.MappingList[i];
if(destinationNode == item.DesNode)
{
return item.Expr;
}
}
return "";
}
看上面两段代码如果不细心,真会认为这完全是一样的,觉得作者简直是白痴。我当时也纳闷,我怎么会写出这么垃圾的代码,于是决定修改
。
1、这两段代码主要的差异在匹配的方式不一样,一个是item.DesNode.StartsWith(parent),要比较的第一个string是否以第二个为前缀;一
个是直接判等,destinationNode == item.DesNode
2、主要的程序逻辑流程毫无差别
解决方案一:合并两个方法,再写一个compare方法,根据传入的type参数,用if语句决定比较的方式
评价:当有新的匹配方式产生时,就需要添加新的if语句,整个方法的结构不能完全固定。
解决方案二:运用strategy模式
该模式适用于将多个逻辑相同的流程抽象成一个流程,并在该流程中包含一种“策略”的模型。
我修改如下:
利用.net库中原有IComparer接口作为“策略”的模型,并将两个匹配的方式写成两个实现这种接口的类,即实现这种策略。
private class ComparerEqual:IComparer
{
#region IComparer 成员
public int Compare(object x, object y)
{
if((string)x == (string)y)
return 1;
return 0;
}
#endregion
}
private class ComparerStartWith:IComparer
{
#region IComparer 成员
public int Compare(object x, object y)
{
if(((string)x).StartsWith((string)y))
return 1;
return 0;
}
#endregion
}
原方法就统一的可以写成:
/// <summary>
/// 通过关联表中的目的路径获得对应的表达式
/// </summary>
/// <param name="path">目的架构中选择的节点的绝对路径</param>
/// <param name="comparer">匹配的方式</param>
/// <returns>对应的表达式</returns>
private string GetExprByDesPath(string path,IComparer comparer)
{
for(int i=0;i<this.relationship.Tables[0].Rows.Count;i++)
{
DataRow item = this.relationship.Tables[0].Rows[i];
if(comparer.Compare((string)item["DesNode"],path) == 1)
{
return (string)item["Expr"];
}
}
return "";
}