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

Class 是否可以将方法/字段放在只由某些派生类使用的基类中,class,inheritance,architecture,software-design,Class,Inheritance,Architecture,Software Design,这是一个通用的软件设计问题。假设您有一个基类和许多派生自它的类(大约10个) 有些类之间共享一些公共功能(3-4个派生类需要它)。基本上是UI控件的字段,创建UI控件的抽象方法,以及使用抽象方法使用抽象方法回收UI片段(8-9行代码)的通用代码。大概是这样的: class BaseClass { ... protected UIControl control; protected abstract UIControl CreateUI(); protecte

这是一个通用的软件设计问题。假设您有一个基类和许多派生自它的类(大约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);
        }
    }

    ...
}
您认为可以将其放在基类中,而不是在派生类中复制代码吗

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

一种替代方法是创建一个从基类派生的中间类,并将其用作需要该功能的类的基类。我觉得为了一个非常特殊的目的,为几行代码创建一个派生类是很沉重的。为此中断继承树是不值得的。我们试图使层次结构尽可能简单,以便易于遵循和理解继承树。如果这是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。一个优点是,在前面提到的继承树之外还有另一个类,它需要这个功能,也可以使用这个实用函数

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

另一种方法是创建从 基类,并将其用作需要 功能

嗯,这是我认为最合适的。但这要视情况而定。这里的主要问题是:需要UI回收的对象与不需要回收的对象真的不同吗?如果它们确实不同,则必须为它们创建新的基类。若差异真的可以忽略不计,我认为把东西留在基类中是可以的

别忘了

我们试图使层次结构尽可能简单,这样就容易了 遵循并理解继承树


我认为这里更重要的是保持事物不仅简单,而且要接近真实世界的事物,这样建模新实体就很容易了。现在看似简单的东西将来可能会带来真正的麻烦。

>是需要UI回收的对象,还是真正不同于不需要回收的对象?除了这个UI回收,它们没有太大的不同。它们没有这样的功能。我暂时不去复制代码,主要是因为逻辑本身非常简单,而且很可能以后不需要维护。关于LSP的观点很好。@nrydn很高兴你解决了这个问题;)谢谢你的提问。