【问题标题】:How to check that I work with instance of subclass?如何检查我是否使用子类的实例?
【发布时间】:2020-06-26 20:47:57
【问题描述】:

我看了一篇关于第三个SOLID原则的有趣文章:https://stackify.com/solid-design-liskov-substitution-principle/

同时,我读到使用instanceof 运算符可能违反了 SOLID 规则。以下问题如何处理。

我有两个类(伪代码):

CoffeeMachine {
    brewCoffee();
}

PremiumCoffeeMachine extends CoffeeMachine {
    brewCoffee()
    brewEspresso()
}

然后在程序的某个地方我得到了一些咖啡机

Set<CoffeeMachine> coffeeMachines

现在我想用每台咖啡机煮咖啡。我怎么知道我可以在不使用 instanceof 运算符的情况下制作浓缩咖啡?

也许这是唯一的方法,但我今天读到很多次instanceof 运算符破坏了 SOLID

您知道一篇有趣的文章,或者您能提供解决此类问题的方法吗?也许我错了,SOLID 说子类不应该包含额外的方法?

【问题讨论】:

  • instanceof 不会破坏 SOLID。您提供的链接上表达的想法是 brewCoffee 的合同不应该在子类中更严格,因为这违反了合同。实际上 Java 不会让你这样做
  • 你为什么想知道它是浓缩咖啡? CoffeeMakeI 可以brewCoffee()。如果您想要浓缩咖啡,只需将您的CoffeeMachine 换成PremiumCoffeMachine,它应该覆盖brewCoffee(而不是brewEspresso)。
  • PremiumCoffeeMachine 有 2 个功能。它可以冲泡简单的咖啡和浓缩咖啡,也许还有其他类型。我想知道我是否可以这样做,因为我更喜欢浓缩咖啡。

标签: java oop solid-principles instanceof


【解决方案1】:

您给出的参考资料提供了很多关于如何处理此问题的见解。

最后,您想要遍历CoffeeMachine 实例中的Collection 并指示它们冲泡咖啡,如brewCoffee() 所述。你是对的,要知道你的机器是否是高级机器,你必须使用instanceof 运算符。

如果您想要更灵活的解决方案,可以使用以下设计:

public interface CoffeeMachine {

    // check if this machine supports a given selection
    // if not, #brewCoffee should throw an exception
    boolean supports(CoffeeSelection selection);
   
    CoffeeDrink brewCoffee(CoffeeSelection selection);
}

现在,可以想象一个支持EspressoCoffeePremiumCoffeeMachine(一个特殊的CoffeeSelection)。 CoffeeSelection ifself 可以是 interfaceclassenum,具体取决于不同咖啡的复杂性和要求。

【讨论】:

  • 我喜欢这个例子。真的很直接
  • 感谢您提供此示例。我也认为这种方法可能是很好的解决方案。据我了解,如果不是更改在超类中设计的逻辑的方法,则使用 instanceof 并没有错。当我使用 instanceof 检查是否可以调用额外的函数时,可以吗?当然,您使用接口的解决方案也很好。它有更好的性能吗?
【解决方案2】:

instanceof 不会破坏 SOLID。您提供的链接上表达的想法是 brewCoffee 的合同不应该在子类中更严格,因为这违反了合同。实际上 Java 不会让你这样做

【讨论】:

  • 请提供一个链接或更多信息,说明为什么基于子类的显式调度不违反 LSP
猜你喜欢
  • 2019-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-17
  • 2011-03-26
  • 2011-01-25
  • 2021-02-03
  • 1970-01-01
相关资源
最近更新 更多