【问题标题】:How to avoid duplication?如何避免重复?
【发布时间】:2017-04-07 10:49:39
【问题描述】:

我正在制作一个 C# 应用程序。该应用程序有两个类和多个方法。在编写代码时,我偶然发现了一个问题。我在两个类中使用相同的两个变量(XList 和 YList)和一种方法。并且可能我需要更多带有此代码的类。所以我创造了一个重​​复问题。以下是我的代码的简单版本:

public class A {
  private testEntities db = new testEntities();
  public List<int> XList = new List<int>();
  public List<int> YList = new List<int>();

  public void GetAllInfo()
  {
    // Get the data from a database and add to a list
    XList = db.Table1.ToList();
    YList = db.Table2.ToList();
  }

  public void DoStuff()
  {
    // Do Stuff with XList and YList
  }
}

public class B {
  private testEntities db = new testEntities();
  public List<int> XList = new List<int>();
  public List<int> YList = new List<int>();

  public void GetAllInfo()
  {
    // Get the data from a database and add to a list (the same as in class A)
    XList = db.Table1.ToList();
    YList = db.Table2.ToList();
  }

  public void DoDifferentStuff()
  {
    // Do ddifferent stuff with XList and YList then in class A
  }
}

我的问题是解决这个重复问题的最佳方法是什么?

经过一些研究,我发现我可能可以通过继承或组合来解决这个问题。我还读到人们选择组合而不是继承。所以我写了以下代码来解决重复:

public class DataPreparation
{
  private testEntities db = new testEntities();
  public List<int> XList = new List<int>();
  public List<int> YList = new List<int>();

  public void GetAllInfo()
  {
    // Get the data from a database and add to a list
    XList = db.Table1.ToList();
    YList = db.Table2.ToList();
  }

  // Implement other methods
}

public class A 
{
  public void MethodName()
  { 
    DataPreparation dataPreparation = new DataPreparation();
    dataPreparation.GetAllInfo();

    UseDataX(dataPreparation.XList);
    UseDataY(dataPreparation.YList);

    // Implementation UseDataX() and UseDataY()
  }
}

public class B 
{
  public void MethodName()
  { 
    DataPreparation dataPreparation = new DataPreparation();
    dataPreparation.GetAllInfo();

    VisualizeDataX(dataPreparation.XList);
    VisualizeDataY(dataPreparation.YList);

    // Implementation VisualizeDataX() and VisualizeDataY()
  }
}

如您所见,我创建了一个类来处理从数据库中获取数据。并且A类和B类使用DataPreparation类。 但这是解决重复问题的最佳方法吗?还是应该使用继承或其他方式?

【问题讨论】:

  • 起点:您打算如何测试您的方法?

标签: c# code-duplication


【解决方案1】:

我认为您可能应该只使用一种称为DoStuff() 的方法,而不是一种称为DoStuff() 和另一种称为DoDifferentStuff() 的方法。

然后您可以创建一个 ABC 来实现公共代码,并在派生类中以不同的方式实现抽象 DoStuff() 方法:

public abstract class Base
{
    private testEntities db = new testEntities();

    public List<int> XList = new List<int>();
    public List<int> YList = new List<int>();

    public void GetAllInfo()
    {
        // Get the data from a database and add to a list (the same as in class A)
        XList = db.Table1.ToList();
        YList = db.Table2.ToList();
    }

    public abstract void DoStuff();
}

public class A: Base
{
    public override void DoStuff()
    {
        // Do Stuff with XList and YList
    }
}

public class B: Base
{
    public override void DoStuff()
    {
        // Do ddifferent stuff with XList and YList then in class A
    }
}

(我也认为拥有这样的公共字段是个坏主意 - 但我猜测/希望这只是示例代码,而您的真实代码没有这些......)

其他代码(创建AB 的代码除外)将通过Base 类类型使用该对象。

【讨论】:

  • 感谢您的回答。是的,这是一个示例,我想将公共字段更改为属性。我对此有几个问题。为此使用继承的原因是什么?例如,为什么不使用组合?你为什么要做一个抽象方法?
  • @BarryStotter 该方法是抽象的,因为基类不知道如何实现该方法。它使用继承,因为这是您拥有在不同派生类中具有不同实现的虚拟方法的唯一方法。您可以通过将 DoStuff() 操作注入构造函数来使用组合来完成此操作,但对于这个特殊问题,我认为这并不比使用继承更好。
  • 当A类中的方法实现与B类中的方法完全不同时,不使用抽象方法会更好吗?或者也许使用组合?
  • @BarryStotter 如果您希望能够将对象传递给可以使用class Aclass B 的方法,那么通常最好使用多态性(即继承)。如果您不想这样做,那么使用组合可能会更好。但是从您的示例中很难分辨出来,因为它不是真正的代码。
【解决方案2】:

一个简单的选择是使用inheritance。创建一个具有共享功能的基类,AB 可以继承。例如:

public abstract class Base
{
    private testEntities db = new testEntities();
    public List<int> XList = new List<int>();
    public List<int> YList = new List<int>();

    public void GetAllInfo()
    {
        // Get the data from a database and add to a list
        XList = db.Table1.ToList();
        YList = db.Table2.ToList();
    }
}

public class A : Base
{
    public void DoStuff()
    {
        // Do Stuff with XList and YList
    }
}

public class B : Base
{
    public void DoDifferentStuff()
    {
        // Do ddifferent stuff with XList and YList then in class A
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-17
    • 2015-09-12
    • 1970-01-01
    • 2019-03-30
    • 2021-11-27
    • 2015-07-30
    • 2011-08-29
    • 1970-01-01
    相关资源
    最近更新 更多