【问题标题】:How to handle the same code path with different parameters?如何处理具有不同参数的相同代码路径?
【发布时间】:2010-12-07 18:13:29
【问题描述】:

我遇到过这样一种情况,即我试图不必修改底层源代码(在那个级别它不是真正的“我的”代码;否则,我很想修改它),我有两个几乎相同的代码路径,但我使用的是不同类型的数据。

忽略您可能很容易将一个转换为另一个,类似的示例将是一个“Circle”对象。

一方面,我有一个Point 对象和一个半径。另一方面,我有一个Circle 对象。这两个都可以描述同一个实际的圆,但我无法将一个转换为另一个。

然后,在我的代码中,我有:

void Run(Circle circle)
{
    if(AllNegative(circle))
    {
        // ...
        // Do unrelated stuff
        // ...
        ColorCircle(circle);
        // ...
    }
}

void Run(Point pt, uint radius)
{
    if(AllNegative(pt, radius))
    {
        // ...
        // Do unrelated stuff
        // ...
        ColorCircle(pt, radius);
        // ...
    }
}

bool AllNegative(Circle circle) { return (circle.AllNegative); }
bool AllNegative(Point pt, uint radius) { return ((pt.X + radius) < 0) && ((pt.Y + radius) < 0); }

void ColorCircle(Circle circle) { /* ... */ }
void ColorCircle(Point pt, uint radius) { /* ... */ }

当然,我在Run 中的代码比本示例中的要多。

如何将Run 合并到一个函数中以尽量减少代码重复?

【问题讨论】:

  • 为什么不能在点/半径和圆之间转换?是什么阻止了你?
  • @Jon Skeet:Circle 类是工厂类;我不能只实例化我自己的 Circle 对象。
  • 并且没有工厂方法可以创建相关的圈子?你不能从圆中得到一个点和一个半径?

标签: c# oop code-duplication


【解决方案1】:

在这种情况下,您可以采取两种方式:

  1. 您可以像现在一样保留它 - 重载方法。
  2. 将重复的代码移至新方法。如果您在 unrelated 部分计算圆的直径(无论是否真实),请创建一个方法 calcDiameter(radius)

在这种情况下重复代码并没有天生的错误,如果只是几行代码并不能真正使新方法实用。

【讨论】:

    【解决方案2】:

    泛型示例:

    public interface ICircle
    {
        Point Point{get;}
        uint Radius{get;}
        ... add whatever you need
    }
    
    public class MyCircle: ICircle
    {
       private Circle _circle;
       ... implement interface
    }
    
    public class MyCircle2: ICircle
    {
       private Point _point;
       private uint _radius;
       ... implement interface
    }
    
    void Run<T>(T circle) where T: ICircle
    {
        if(AllNegative(circle))
        {
            ColorCircle(circle);
        }
    }
    

    【讨论】:

    • ColorCircle(circle);不是暗示PointRadius可以转成Circle吗?
    • 否,因为 Run 方法现在只有 ICircle 接口。不方便的是您需要定义两个“包装器”类,MyCircle 和 MyCircle2 - 名称很愚蠢 :)
    • 但是ICircle 接口不包含ColorCircle 工作所需的信息。或者,至少您正在复制 MyCircle 类的点/半径信息(因为它可能包含在 Circle
    【解决方案3】:

    至少,您可以在一个单独的方法中执行您的unrelated stuff,并从每个Run 调用它。

    【讨论】:

      【解决方案4】:

      您可以为它们创建一个通用接口,如下所示:

      public interface IMyShape
      {
          public bool IsNegative();
          public void Color();
      }
      

      那么您只需要一种接受 IMyShape 引用的方法:

      void Run(IMyShape shape)
      {
          if(shape.AllNegative())
          {
              // ...
              // Do unrelated stuff
              // ...
              shape.Color();
              // ...
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-28
        • 1970-01-01
        相关资源
        最近更新 更多