【问题标题】:oop: Composition or Inheritance in concrete caseoop:具体案例中的组合或继承
【发布时间】:2010-08-10 19:02:24
【问题描述】:

我们刚刚与大学讨论过以下样式是否可以用于 oop。

我们有一个类,它有一个公共函数,并且在构造函数中需要一个阅读器:

public class Converter
{
    private readonly IReader _reader;

    public Converter(IReader reader)
    {
        _reader = reader;
    }

    public byte[] Convert(...params...)
    {
         return something;
    }
}

我们有 Reader1 和 Reader2,它们都实现了 IReader。

我想设置两个管理器:Converter1 和 Converter2,提供相同的公共 Convert() 函数,但 Converter1 将使用 Reader1,Converter2 将使用 Reader2。

对我来说,最简单的解决方案是从 Converter 继承并使用适当的阅读器对其进行初始化:

public class Converter1 : Converter
{
    public Converter1():base(new Reader1())
    {}
}
public class Converter2 : Converter
{
    public Converter2():base(new Reader2())
    {}
}

我的大学说,Converter1 和 Converter2 是 Manager,不应该对 manager 使用继承,而是应该在这里应用组合。但从我的角度来看,组合只会导致特定转换器类中的额外代码。

那么,您能否请教一下,在实现管理器时是否可以使用继承? 谢谢

【问题讨论】:

    标签: c# oop


    【解决方案1】:

    你为什么要继承?

    根据您提供的示例,除了确保 Converter1/Converter2 强制执行特定类型的读取器之外,您没有对基类执行任何其他操作。

    在我看来,你的同事是对的。你应该做的是实现一个工厂方法,它将为你创建和填充正确配置的转换器。

    public static class ConverterFactory {
        public static CreateConverter1() { 
           return new Converter(new Reader1());
        }
        public static CreateConverter2() {
           return new Converter(new Reader2());
        }
    }
    
    ...
    Converter x = ConverterFactory.CreateConverter1();
    

    【讨论】:

      【解决方案2】:

      在我看来,这是对继承的滥用。您没有专门研究转换器的行为 - 您只是专门研究构造

      特别是,您可以轻松地拥有一个带有静态方法的静态类来执行此构造:

      public static class Converters
      {
          public static Converter CreateConverter1()
          {
              return new Converter(new Reader1());
          }
      
          public static Converter CreateConverter2()
          {
              return new Converter(new Reader2());
          }
      }
      

      当然,这些甚至可以是普通 Converter 类中的静态方法。

      这没有失去任何功能的事实表明继承是一个错误。

      再说一次,我经常怀疑继承。正确设计继承意味着制定扩展点,记录它们的行为方式——这是在为调用者提供足够的信息以预测一致的行为和为实现者提供足够的回旋空间以以有用的方式改变行为之间的平衡行为。在这里,您没有执行任何操作 - 您只是更改了将读取器传递给构造函数的内容。

      【讨论】:

      • 静态方法并非如此,因为我需要将那些 Converter1/Conerter2 推送到其他类的构造函数中,并且调用静态方法将无法进行单元测试。将工厂注入消费者类也太多了。我绝对需要两个管理器类,但你可能是对的,继承不是这里最好的东西.. :)
      【解决方案3】:

      要么使用继承(就像你建议的那样),要么只使用一个可以与多态 IReader 一起使用的 Converter 类。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-24
        • 1970-01-01
        • 1970-01-01
        • 2013-02-11
        相关资源
        最近更新 更多