gpt4 book ai didi

java - 如何以及何时在 Java 中使用 Kotlin 密封类?

转载 作者:行者123 更新时间:2023-12-04 07:23:52 26 4
gpt4 key购买 nike

考虑到误用密封类,我们来看看下面的设计。
有两个模块:

  • parser (Kotlin) - 负责从 String
  • 创建实例
  • processor (Java) - 将原始传入数据泵入强类型存储(即关系表)
  • 字符串来自外部源到 processor
  • processor将其认可委托(delegate)给 parser
  • parser生成不同类型的实例 [Banana, Nail, Shoe]基于一些rules X
  • processor根据一些 rules Y 将每个实例持久化到适当的表中

  • 像这样在 parser 中使用密封类是否合适?之后在 processor根据每个实例的具体类型做出决定?
    // parser module exposes Item and its subclasses

    sealed interface Item {
    class Banana(/*state 1*/) : Item
    class Nail(/*state 2*/) : Item
    class Shoe(/*state 3*/) : Item
    }

    fun parse(value: String, rule: ParseRule): Item {
    return when (true) {
    rule.canParseBanana(value) -> rule.makeBananaFrom(value)
    rule.canParseNail(value) -> rule.makeNailFrom(value)
    rule.canParseShoe(value) -> rule.makeShoeFrom(value)
    else -> throw RuntimeException("cannot parse")
    }
    }

    // processor module makes decisions based on class

    void process(String value){
    Item item = parser.parse(value);

    if (item instance of Item.Banana){
    persistBanana((Item.Banana) item)
    } else if ( ... )
    // etc
    } else {
    throw new RuntimeException("Unknown subclass of Item : " + item.getClass())
    }
    }
    我发现这种方法有问题,因为越来越多的 Item 子类可能会导致设计灾难,但无法弄清楚是否存在与此完全不同的密封类的“规范”用例。
    什么是密封类适用性的限制,当系统设计者应该更喜欢“较少类型”的东西时,如下所示:
    class Item{
    Object marker; // String or Enum
    Map<String, Object> attributes;
    }

    // basically it is the same, but without dancing with types
    void process(String value){
    Item item = parser.parse(value);

    if ("BANANA".equals(item.marker)){
    persistBanana(item.attributes)
    } else if (...){
    // etc
    }
    }

    最佳答案

    您可以使用访问者模式来提供 when .. is Java 的风格方法。

    // Kotlin
    abstract class ItemVisitor<OUT> {
    operator fun invoke(item: Item) = when (item) {
    is Banana -> visitBanana(item)
    is Shoe -> visitShoe(item)
    is Nail -> visitNail(item)
    }
    abstract fun visitBanana(item: Banana): OUT
    abstract fun visitShoe(item: Shoe): OUT
    abstract fun visitNail(item: Nail): OUT
    }
    因为项目是密封的,所以您不需要 else案例 when然后 Java 代码可以创建访问者而不是自己创建访问者 instanceofelse 核对,如果您添加一个变体,您添加一个方法并被提醒您的访问者的 Java 实现需要新方法。

    关于java - 如何以及何时在 Java 中使用 Kotlin 密封类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68326298/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com