【问题标题】:How to remove duplicate code for all classes implementing an interface without inheriting from a concrete class?如何在不继承具体类的情况下删除所有实现接口的类的重复代码?
【发布时间】:2009-12-14 16:18:02
【问题描述】:

我有一个设计模式问题。 我有一个类似于 CAB(复合应用程序块)的智能客户端应用程序框架,我们称之为小部件框架。 我们可以将应用程序的模块定义为“小部件”,并且有一个列出所有小部件的配置文件。 小部件是任何实现 IWidget 接口的类。 所有小部件都有加载子小部件的代码,并且该代码是相同的。 如何在所有这些小部件之间共享该代码,而不强制小部件从具体类继承? 在这种情况下,最佳做法是什么? 这种情况有设计模式吗?

谢谢

【问题讨论】:

    标签: design-patterns


    【解决方案1】:

    您可以使用复合方法,创建一个名为 SubWidgetLoader 或类似的对象,然后使 IWidget 的所有实例都包含加载器类的实例。

    【讨论】:

      【解决方案2】:

      听起来Decorator pattern 可以用来为每个类添加“加载子小部件”方法。该模式允许在不依赖继承的情况下针对不同的类更改“加载子小部件”方法。

      【讨论】:

        【解决方案3】:

        这听起来像是使用从接口继承的抽象类的完美可能性。但似乎有理由不这样做。

        您可以生成一个类来封装小部件类的所有重复代码,然后在每个小部件中创建此类的对象。现在代码只在一个类中,但每个小部件都可以从他自己的对象中调用函数来使用重复代码的功能。

        【讨论】:

          【解决方案4】:

          我会通过聚合来做到这一点。创建一个WidgetLoader 类,并在内部使用它来实现您的子小部件加载功能。

          这使加载功能与 Widget 类的主要意图分离,避免继承,并且如果通过工厂实例化,可以使其松散耦合。

          【讨论】:

            【解决方案5】:

            如果您不想使用通用代码扩展超类,您可以尝试使用委托并包装通用功能,我们称之为 SubWidgetLoader 。那就是创建一个实现通用功能的类,并让您的 IWidget 对象包含 SubWidgetLoader。这样每个单独的 Widget 就不必重复代码,而是调用 SubWidgetLoader 类来执行工作。

            【讨论】:

              【解决方案6】:

              为什么不从基类继承?

              您的情况似乎很适合template method pattern。我认为继承是最好的解决方案,除非有充分的理由不这样做。在您的具体情况下,从 BaseWidget 继承似乎也是合乎逻辑的步骤。

              注意:我知道您特别询问如何不使用继承,但您没有告诉我们原因。我认为,如果有人特别要求一些违背我通常的软件开发倾向的东西,他应该不仅解释什么,而且解释为什么,如果他不这样做,我拒绝简单地提供答案(如果我知道的话),如果我认为仅仅是“设计”是错误的。

              【讨论】:

              • 他试图避免从 concrete 基类继承。这是一个好主意,因为从具体类继承本质上是脆弱的。基类不知道它的内部实现可能被依赖。这是一个风险——如果基类实现发生变化,你继承的类可能会中断。参见例如en.wikipedia.org/wiki/Fragile_base_class.
              • 嗯,我明白了...在 stackoverflow 中您没有一天不学习新东西...但是模板方法模式专门指的是从基本抽象类继承,而不是具体的。
              【解决方案7】:

              为什么要避免让它们都派生自一个公共基类?它可能是一个抽象基类,因为您担心它们不是从具体基类继承的。抽象基类可以提供它们都共享的“加载子小部件”功能。

              但是,如果您一心想要避免继承,那么 Builder 模式似乎很适合重用构建子小部件树的代码,而无需引入基类。

              http://en.wikipedia.org/wiki/Builder_pattern

              【讨论】:

                【解决方案8】:

                在其他语言中,这可以通过 mixins 来实现。在 C# 中,您可以通过在接口上定义扩展方法来获得一些接近...

                interface IWidget
                {
                    ICollection<IWidget> SubWidgets { get; set }
                }
                
                static class WidgetExtensions
                {
                    static public void LoadSubWidgets(this IWidget widget)
                    {
                        widget.SubWidgets.Add(GetSomeWidgetDependency());
                    }
                }
                

                【讨论】:

                • 免责声明:正如其他人所说,从抽象基类继承会更好。我只是提供另一种选择..
                猜你喜欢
                • 2019-05-10
                • 2018-07-08
                • 1970-01-01
                • 2022-01-23
                • 2021-11-16
                • 1970-01-01
                • 2023-03-24
                • 2015-12-18
                • 1970-01-01
                相关资源
                最近更新 更多