【问题标题】:Is it OK to subclass solely to provide default state/configuration?仅子类化以提供默认状态/配置是否可以?
【发布时间】:2013-08-12 01:35:35
【问题描述】:

假设您有一个支持将 GUI 组件相互嵌套的 GUI 框架。让我们将任何可以包含其他 GUI 组件的 GUI 组件的基类称为 Container。

子类化 Container soley 是否可以提供默认配置,或者子类化是否应该始终提供添加/覆盖/实现的行为?例如,假设我想制作一个 ButtonBar 容器,它填充 100% 的屏幕宽度,高度为 50 像素,并水平布置其组件。要配置这样的容器,我可以执行以下两个示例之一:

Container container = new Container();
container.PercentWidth = 100;
container.Height = 50;
container.Layout = Layout.Horizontal;

// use container

或者,(这是我的问题),这样做可以吗:

public class ButtonBar : Container
{
    public ButtonBar()
    {
        PercentWidth = 100;
        Height = 50;
        Layout = Layout.Horizontal;
    }
}

ButtonBar buttonBar = new ButtonBar();
// use buttonBar

ButtonBar 对容器没有额外的功能,并且不会覆盖任何容器方法。它只是用来简化将 Container 配置为 ButtonBar。

编辑

我的结论是最好使用返回Container的工厂,例如widgetFactory.CreateButtonBar();这样,您最终会使用抽象类型(Container),并将类型的“设置”封装在工厂中,这就是工厂所做的。

public class WidgetFactory
{
    public Container CreateButtonBar()
    {
        Container container = new Container();
        container.PercentWidth = 100;
        container.Height = 50;
        container.Layout = Layout.Horizontal;   

        return container;
    }
}

【问题讨论】:

  • 如果一致性是你所追求的,那么它可能没问题......
  • 这是 WPF 中相对常见的做法,例如,应用全局样式(在这种情况下,您的子类中甚至没有任何代码,它只需要存在即可。)跨度>

标签: c# oop derived-class subclassing


【解决方案1】:

如果某些人创建子类只是为了覆盖方法,那么您的方法同样正确。 OOP 的主要原因之一是程序的简单模块化设计。当您从哲学的角度考虑它时,您的按钮栏是一种与容器不同的对象,在小程序中差异可能看起来微不足道,但在较大的程序中,它可以使程序的差异易于理解。

【讨论】:

    【解决方案2】:

    实际上,没有什么可以反对您采用的方法。唯一的问题是这里看到的是 C# 没有多重继承,所以你只能继承一个“容器”。

    不如只将容器作为一种模板并访问该容器的属性?

    这里是例子

    public enum ContainerLayout {
        Horizontal,
        Vertical
    }
    
    public class Container
    {
        public int PercentWidth { get; set; }
        public int Height { get; set; }
        public ContainerLayout Layout { get; set; }
    }
    
    public class ButtonBar
    {
        public Container containerTemplate = null;
    
        public ButtonBar(Container strategy)
        {
            containerTemplate = strategy;
        }
    }
    
    // Creation would be
    ButtonBar btnBar = new ButtonBar(
        new Container()
        {
            PercentWidth = 100,
            Height = 700,
            Layout = ContainerLayout.Horizontal
        }
    );
    

    【讨论】:

    • [quote]实际上,没有什么可以反对您采用的方法。[/quote] 很高兴听到这句话,这就是我一直在寻找的答案。即使您的解决方案摆脱了 ButtonBar 继承 Container,它也摆脱了 ButtonBar 也可以被视为 Container,这似乎是不可取的。
    • 你说得对。也许遵循 tge 适配器模式会产生您需要的结果,并且将是一种标准方法。只是不确定你打算用你的设置做什么
    猜你喜欢
    • 1970-01-01
    • 2021-10-26
    • 1970-01-01
    • 1970-01-01
    • 2019-03-24
    • 2014-11-03
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多