如何从 Scala public API 中屏蔽实现级别 类、特征和对象?

How can I shield implementation level classes, traits and objects from Scala public APIs?

我想减少泄漏到我的 Scala public API 中的实现级别细节,并且有太多旋钮可用于调整可见性,以至于我的头因试图而旋转算出:

What is the best way to shield implementation level classes, traits and objects from Scala public APIs ?

我能想到的最好的办法就是这样做:

package restaurant {
  trait Service {
    acceptOrder(dish: String, quantity: Int)
  }

  package impl {
    private class ServiceImpl {   // mark this & everything else in package as private
      acceptOrder(dish: String, quantity: Int) = println("order accepted")
    }

    private class ServiceHelper { // mark this & everything else in package as private
      def helpDoStuff() = ???
    }
  }
}

但请注意,我必须用 'private' 标记 impl 包中的所有内容, 随着包裹中物品数量的增加,这会变得非常乏味(并且容易忘记)。如果 Scala 可以选择将 > 包 < 声明为私有的,或者至少将包中所有内容的默认可见性设置为对该包私有,那就太好了。但这似乎不存在。

我确定有执行此操作的最佳实践模式...如果您知道,请告诉我。

更新:我确实在 Programming Scala 书中读到了包对象。这似乎是将所有内容集中在 public API 中的好方法。但是包对象似乎没有提供一种方便的方法来隐藏所有不在包对象中的对象的可见性。

IDEA 用户的旁注: 我的嵌套方法的一个问题是它似乎弄乱了 IDEA 中的自动缩进。对我来说,另一个问题是找到解决方法。我向 Intellij 提交了一个错误(如果你们中有人遇到这个问题并想对其进行投票:https://youtrack.jetbrains.com/issue/IDEA-144872

好问题!

使用私有对象怎么样?当然,这只有在你可以的情况下才有效 在单个文件中实现您的服务。否则我认为 impl 命名空间方法是你能做的最好的。

package restaurant

sealed trait Service {
  def acceptOrder(dish: String, quantity: Int): Unit
}

object Service {
  def create: Service = new Impl.ServiceImpl()

  private object Impl {
    class ServiceImpl extends Service {
      def acceptOrder(dish: String, quantity: Int) = println("order accepted")
    }

    class ServiceHelper {
      def helpDoStuff() = ???
    }
  }
}

标准方式就是

package restaurant {
  trait Service {
    acceptOrder(dish: String, quantity: Int)
  }

  private[restaurant] class ServiceImpl {
    acceptOrder(dish: String, quantity: Int) = println("order accepted")
  }

  private[restaurant] class ServiceHelper {
    def helpDoStuff() = ???
  }
}

但是,是的,重复这些非常乏味。