【问题标题】:How to refactor these methods to avoid duplication?如何重构这些方法以避免重复?
【发布时间】:2011-11-01 23:25:15
【问题描述】:

在我们的代码库中

public ActionResult Copy(string id, string targetId)
            {
                //lot of similar code
                Copy(sourcePageRef, destinationPageRef);
                //lot of similar code
            }

public ActionResult Move(string id, string targetId)
        {
            //lot of similar code
            Move(sourcePageRef, destinationPageRef);
            //lot of similar code
        }

问题是,Copy 和 Move 有不同的签名:

PageRef Copy(PageRef, PageRef)

void Move(PageRef, PageRef)

如何重构这些方法以避免重复? 谢谢

【问题讨论】:

  • 如果您可以丢弃复制操作的结果,这通常是您使用外观模式的地方。使用相同的签名在您的外观中实施复制和移动,然后您可以反射性地调用它们或您喜欢的任何方式。否则,我会先将通用代码移到辅助方法中。

标签: c# .net refactoring


【解决方案1】:

如果您不需要Copy 的结果,您仍然可以使用Action<string, string> 或任何类型:

public ActionResult Copy(string id, string targetId)
{
    CopyOrMove((x, y) => Copy(x, y));
}

public ActionResult Move(string id, string targetId)
{
    CopyOrMove(id, targetId, (x, y) => Move(x, y));
}

private void CopyOrMove(string id, string targetId,
                        Action<string, string> fileAction)
{
    // lot of similar code
    fileAction(sourcePageRef, destinationPageRef);
    // lot of similar code
}

这是一个选项。这取决于“大量类似代码”真正在做什么,以及第二个块是否需要第一个块的结果。例如,如果你可以这样做:

public ActionResult Copy(string id, string targetId)
{
    string sourcePageRef = PrepareSourceFile(id, targetId);
    string targetPageRef = PrepareTargetFile(targetId);
    Copy(sourcePageRef, targetPageRef);
    CleanUp(sourcePageRef, targetPageRef);
    return ...;
}

public ActionResult Move(string id, string targetId)
{
    string sourcePageRef = PrepareSourceFile(id, targetId);
    string targetPageRef = PrepareTargetFile(targetId);
    Move(sourcePageRef, targetPageRef);
    CleanUp(sourcePageRef, targetPageRef);
    return ...;
}

...那么这可能比使用委托重构方法更简单。

【讨论】:

    【解决方案2】:

    我不会重构这些方法,但如果可能的话,将这些方法的内容放入单独的私有函数中,在一种情况下移动数据,在另一个副本中。所以你提供的方法可以使用它。从方法的名称可以很清楚地看出它的作用,恕我直言,不要更改它,因为它们是公共的并且对您的类消费者也是可见的。

    【讨论】:

      【解决方案3】:

      提取这些:

      //很多类似的代码

      到他们自己的方法,只需从您的 Move 或 Copy 方法中调用它们。

      【讨论】:

        【解决方案4】:

        我看到了 2 个选项: 选项 A)使用分解方法提取公共代码,并从每个重复的方法中对该代码进行分类:

          Copy(,) {
            CommonCodeA();
            Copy(..);
            CommonCodeB();
          }
        
          Move(,) {
            CommonCodeA();
            Move(..);
            CommonCodeB();
          }
        
          CommonCodeA() {...}
        
          CommonCodeB() {...}
        

        选项B)使用模板方法重构:将公共代码放在超类方法中,并让该方法调用特定代码的抽象方法。然后为每个重复的方法创建一个子类,实现抽象方法。

         class OperationAction {
        
              operation() {
                   //lots of code
                   do(,);
                   //lots of code
              }
              abstract do();
         }
        
         class CopyAction extends OperationAction {
             do() {
                  Copy(srcref,destref);
             }
             Copy(srcref,destref) { ... }
         }
        
         class MoveAction extends OperationAction {
             do() {
                  Move(srcref,destref);
             }
             Move(srcref,destref) { ... }
         }
        

        【讨论】:

          猜你喜欢
          • 2013-09-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-06-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多