是出口第三方库依赖项良好的编程实践?

时间:2015-09-07 12:00:46

标签: scala dependencies singleton

我正在使用Intellij 14,在模块设置中,有一个导出依赖项的选项。

我注意到当我编写扩展特征的对象时,我需要在其他模块尝试使用这些对象时在模块设置中选择 export

例如,

object SomeObj extends FileIO

会要求我导出 FileIO 依赖项。

但是,如果我编写一个在调用对象时创建新实例的伴随类,则不再需要导出。

object SomeObject {
   private val someObject = new SomeObject()
   def apply() = someObject
}

private[objectPkg] class SomeObject() extends FileIO {}

这段代码对于Scala的单例模式更加冗长和类似。使用您的模块导出第三方依赖项是否有用?如果没有,我的模式是Scala的典型解决方案吗?

1 个答案:

答案 0 :(得分:0)

这一切都涉及代码设计原则。基本上,如果您以后可以切换底层第三方库,或者您的系统必须灵活地移植到其他一些库 - 那么隐藏实现背后的实现是必须的。

通常在java / scala中有一组现成的接口,这些接口是在第三方中实现的,你可以将它们作为外观的一部分用于系统的其他部分,总的来说它是一个 java 方式。如果不是这种情况 - 您需要自己派生接口。每个人的价值都是在自己的背景下估计的。

根据您的情况:请记住,在java / scala中导出名称,如果您只是在定义代码之外以任何方式使用您的类(扩展FileIO),这意味着类是公开访问,其类型也在外部导出/泄露。如果某个私有类逃避其可见范围,Scala应该抛出编译错误(所以在SomeObject的第二个版本中可能就是这种情况。)

考虑这个例子:我经常在我的应用程序中使用typesafe配置库。它有方便的方法,但我通常留出空间以便可能分离(或者更确切地说是我自己的扩展):

package object config {
  object Config {
    private val conf: TypeSafeConfig = ConfigFactory.load()

    def toTypeSafeConfig: TypeSafeConfig = conf
  }

  @inline implicit def confToTypeSafeConfig(conf: Config.type): TypeSafeConfig = conf.toTypeSafeConfig
}

隐式转换只允许我调用TypeSafeConfig上的所有Config方法,它有一堆方便的方法。理论上,将来我可以删除我在Config对象中使用的隐式和实现方法。但我很难想象为什么我会花时间在这上面。这是泄露实现的一些例子,我认为没有问题。