【问题标题】:Builder Pattern and LSP构建器模式和 LSP
【发布时间】:2020-09-04 07:19:23
【问题描述】:

我正在经历 Builder 模式,并且有几个我认为需要澄清的问题

  1. 构建器模式是通过抽象类还是通过接口实现的。使用接口https://sourcemaking.com/design_patterns/builder的帖子很少
    https://refactoring.guru/design-patterns/builder
    ...可以列出更多
    还有人使用抽象类https://www.dofactory.com/net/builder-design-pattern

注意:我认为它应该使用抽象类来实现。这个理由是基于这样的假设,即我可能/可能不会在派生类中实现它们(因为可能有一些具体类没有实现它们)...
不过,这种假设可能是完全错误的。

  1. 如果上述假设是错误的,那么它不会违反 LSP。由于 LSP 中的一个条件表明您的派生类中不能有“未实现的方法”。

或者我完全误解了它......

【问题讨论】:

  • 我认为与构建器合作的最佳方式是通过接口,而不是抽象类。当您调用构建器上的函数(例如setX)来引发异常(例如Unimplemented Function)时,这会很奇怪。 意见>
  • 那么,如果我有一个实现 IBuilder 的具体类并且不实现任何一种方法会发生什么。那不是违反LSP吗?..
  • 是的,在我看来,在这种模式下有一个未实现的函数是一种味道,它会让你的代码更难维护和测试,因为它迫使客户端代码知道哪些方法不可用不同的用例。
  • “不实现”一个方法是什么意思?如果一个方法没有实现,那个特定的类必须被声明为“抽象”,以便编译,所以它不能被实例化,所以它不能违反 LSP。实现接口或扩展抽象类也是如此。

标签: oop design-patterns solid-principles


【解决方案1】:

评论太长了...

GoF 书中的模式早于 Java。是 Java 后来引入了接口和抽象类之间的(愚蠢的)区别。当 GoF 指代一个接口时,它们仅表示一个抽象,您可以使用任何支持抽象的语言特性来实现它。

话虽如此,GoF 构建器模式过于复杂。 The pattern is useful even without polymorphism. 我认为这就是它最常实现的方式。如果您使用的是 Java,那将是来自 Effective Java 的 Josh Bloch 的构建器模式。

我并不是要忽略 LSP 的问题,但如果这里的真正目标是学习有效地使用 Builder,那么我的建议是忽略 GoF 中的(过时的)版本,并查看一个现代实现,其中这个问题不存在。如果您真的想询问 LSP,那么我建议您提出一个专门针对该主题的新问题,与 Builder 模式分开。

为了更直接地解决 OP 中的问题,

  1. 构建器模式可以通过抽象类或接口来实现。哪个没关系。现代实现更经常使用两者。
  2. LSP 一致性将取决于您如何实现(和记录)该模式。使用接口或抽象类可能会违反(或不违反)LSP。消除两者可以消除这个问题。

【讨论】:

    猜你喜欢
    • 2011-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-21
    • 2013-07-26
    相关资源
    最近更新 更多