我正在使用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的典型解决方案吗?
答案 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
对象中使用的隐式和实现方法。但我很难想象为什么我会花时间在这上面。这是泄露实现的一些例子,我认为没有问题。