使用隐式转换代替适配器模式

时间:2013-07-21 08:05:58

标签: scala implicit-conversion

我有一个用MVC风格编写的项目。视图看起来像这样:

trait BaseView {
  def asComponent(): Component // each view can be displayed on screen
}


class ConcreteView extends Panel with BaseView  {

  def asComponent(): Component = this //ConcreteView is itself Component because it extends Panel 
}

可以更改此代码以使用从ConcreteViewComponent的隐式转换吗?所以我可以使用ConcreteView作为Component(由于隐式转换)而不调用ConcreteView#asComponent方法?

1 个答案:

答案 0 :(得分:3)

是的,有可能。只需定义从BaseView到Component的隐式转换,调用asComponent方法。

object BaseView {
  implicit def viewIsComponent(x:BaseView) : Component = x.asComponent
}

但这并不意味着这是一个好主意。 scala中的隐式转换是一个非常强大的功能。如果BaseView(并通过继承每个XXXView)是一个组件,这意味着当你想调用val myView的方法时,你将获得Component的所有方法:SomeView。这完全混淆了命名空间,也可能很危险,因为你不确定是否调用了View或方法隐式映射到的方法。

在scala库中,已经从隐式转换转向更明确,更冗长的方式。以JavaConversions为例:它们提供从scala集合到java集合的隐式转换。这听起来是个好主意,但它在实践中造成了很多麻烦:

  • 当你不指望他们
  • 时发生转换
  • scala集合的命名空间与来自Java等效的
  • 中的许多其他方法混杂在一起
  • 在将新方法添加到与转换源中的方法发生冲突的隐式转换的目标时很难找到问题

目前推荐的处理java / scala集合互操作的方法是使用更明确的JavaConverters,它将单个方法asScala添加到java集合中,并将asJava添加到scala集合中。

所以请保持原样。也许将名称更改为.component,因为您实际上并没有视图转换为组件,而只允许某人访问每个视图必须具有的组件。