【问题标题】:Kotlin multiple interface delegationKotlin 多接口委托
【发布时间】:2021-02-20 06:28:49
【问题描述】:

如何在 Kotlin 中高效地编写委托?

我有以下问题:

我正在向我的客户公开一个接口。我们就叫它ExternalInterface吧。

interface ExternalInterface {
  fun fun1()
  fun fun2()
  fun fun3()
  fun fun4()
}

我在我的包中实现这个没有委托如下:

class Impl(
   obj1: InternalInterface1,
   obj2: InternalInterface2
): ExternalInterface {
     override fun fun1() = obj1.fun1()
     override fun fun2() = obj1.fun2()
     override fun fun3() = obj2.fun3()
     override fun fun4() = obj2.fun4()
}

这是因为通过一些内部分类更容易对功能进行分组,所以我可以有如下内容:

class RelatedStuff : InternalInterface1 {
  ....
}

class OtherRelatedStuff : InternalInterface2 {
  ....
}

我的内部接口只是外部接口的细分:

interface InternalInterface1 {
   fun fun1()
   fun fun2()
}

interface InternalInterface2 {
   fun fun3()
   fun fun4()
}

是否可以在这里以我的客户仍然可以依赖ExternalInterface 但我可以清理Impl 类代码的方式使用委托?

实际上,我想我想到达类似的地方:

class Impl(
   obj1: InternalInterface1,
   obj2: InternalInterface2
): InternalInterface1 by obj1, InternalInterface2 by obj2

但也希望它实现ExternalInterface

【问题讨论】:

  • 是什么阻止您简单地将, ExternalInterface 添加到此类正在实现的接口上?
  • @Tenfour04,嗯,所以你的意思是我补充说,因为这个类现在有两个具有相同方法的接口,它们都是因为单一定义而被处理的?我的意思是,它可以工作,只是不确定,为两个接口 API 提供一个实现方法是一个好习惯。
  • 由于它已经实现了 ExternalInterface 所需的所有方法签名,如果您声明它,它也满足该接口。就个人而言,我倾向于避免接口方法之间的签名重叠,因为我认为这很可能容易出错。但在这种情况下,您的其他接口是内部的,您可以将它们记录为纯粹用于委派一部分 ExternalInterface。
  • 如果它们不必是内部的,您可以让 ExternalInterface 扩展其他两个接口以避免重叠方法签名的歧义。
  • @Tenfour04,是的,就我而言,我不能将它们放在外部,因为它具有外部接口包所没有的依赖变量。

标签: function kotlin delegates


【解决方案1】:

您可以简单地创建第三个接口(在我的示例中为Facade)并让Impl 也实现它:

interface InternalInterface1 {
   fun fun1()
   fun fun2()
}

interface InternalInterface2 {
   fun fun3()
   fun fun4()
}

interface Facade : InternalInterface1, InternalInterface2

class Impl(
   obj1: InternalInterface1,
   obj2: InternalInterface2
): InternalInterface1 by obj1, InternalInterface2 by obj2, Facade

虽然这个设计对我来说有点奇怪。我通常做的是我有一堆外部接口(我称之为API)和一些扩展API接口的内部接口:

interface ExternalInterface1 {
    fun fun1()
}

interface ExternalInterface2 {
    fun fun2()
}

interface InternalInterface1 : ExternalInterface1 {
    fun fun3()
}

interface InternalInterface1 : ExternalInterface2 {
    fun fun4()
}

interface ExternalAPI: ExternalInterface1, ExternalInterface2

interface InternalAPI: InternalInterface1, InternalInterface2

class Impl: InternalAPI {
    obj1: InternalInterface1,
    obj2: InternalInterface2
}: InternalAPI, InternalInterface1 by obj1, InternalInterface2 by obj2

这样你的外部接口是原始的,但你仍然可以使用你的InternalAPI 来拥有一些内部接口。然后你可以添加这样的东西:

/**
 * Exposes the internal API of [ExternalAPI]. Note that all methods exposed this
 * way are subject to change!
 */
fun asInternal(): InternalAPI = this

每个人都很开心。

【讨论】:

    猜你喜欢
    • 2020-08-22
    • 1970-01-01
    • 2018-03-05
    • 2012-06-25
    • 2019-09-08
    • 1970-01-01
    • 2014-08-18
    • 2017-11-28
    • 2018-05-07
    相关资源
    最近更新 更多