代码重构中发现的设计模式的运用

前天写好了表单映射这一块的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 "";
  }

posted on 2005-08-12 12:50  栖息的熊  阅读(637)  评论(1编辑  收藏  举报

导航