是否可以将方法/字段放到仅由某些派生类使用的基类中

时间:2015-03-30 19:15:05

标签: class inheritance architecture software-design

这是一个通用的软件设计问题。假设你有一个基类和许多从它派生的类(大约10)。

在某些类之间共享一些常见功能(3-4个派生类需要它)。基本上是用于UI控件的字段,用于创建UI控件的抽象方法以及使用抽象方法来回收UI片段(8-9行代码)的公共代码。像这样:

class BaseClass {
    ...

    protected UIControl control;

    protected abstract UIControl CreateUI();

    protected void RecycleUI() {
        if (/* some condition is met */) {
            if (this.control != null) {
                control.Dispose();
            }
            this.control = this.CreateUI();
            this.AddToUITree(control);
        }
    }

    ...
}

您认为将它放到基类而不是在派生类中复制代码是否可以。

缺点是这段代码仅用于某些基类,而与其他类完全无关。

另一种方法是创建一个派生自BaseClass的中间类,并将其用作需要该功能的中间类。我觉得为一个非常特定的目的创建一个代码行的派生类感觉很重。它并不觉得值得为此中断继承树。我们尽量保持层次结构尽可能简单,以便易于理解继承树。也许如果这是C ++,其中多继承是一个选项,它不会是一个大问题,但多重继承是不可用的。

另一种选择是创建实用程序方法和界面来创建/更新UI控件:

interface UIContainer {
    UIControl CreateUIControl();

    UIControl GetUIControl();

    void SetUIControl(UIControl control);
}

class UIControlUtil {
    public void RecycleUI(UIContainer container) {
        if (/* some condition is met */) {
            if (container.GetUIControl() != null) {
                container.GetUIControl().Dispose();
            }
            UIControl control = container.CreateUI();
            container.SetUIControl(control);
            container.AddToUITree(control);
        }
    }
}

我不喜欢这个选项,因为它会外部渗透UI逻辑,因为它的UI状态可以在外部操作,所以安全性较低。派生类现在也必须实现getter / setter。一个优点是在前面提到的继承树之外还有另一个类,它需要这个功能,它也可以使用这个实用功能。

你还有其他建议吗?我是否应该抑制在我体内冲泡的冲动,让公共代码不再重复?

1 个答案:

答案 0 :(得分:1)

  

另一种方法是创建一个派生自的中间类   BaseClass并将其用作需要的基础   功能。

嗯,这是我认为最合适的。但这取决于。这里的主要问题如下:是需要UI回收的对象,与那些不同的对象,不是吗?如果它们真的不同,则必须为它们创建一个新的基类。如果差异确实可以忽略不计,我认为将事情留在基类中是可以的。

不要忘记LSP

  

我们尽量保持层次结构尽可能简单,这样很容易   遵循和理解继承树

我认为更重要的是保持事物不仅简单,而且接近现实世界的东西,以便建模新实体很容易。现在看似容易,可能会在未来造成真正的麻烦。