2013-07-21 46 views
0

我有一個用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方法?

+2

爲什麼你甚至需要這樣的方法? 'val c:Component = someConcreteView'應該已經可以工作了。 –

+0

要更好地瞭解何時以及何時不應使用適配器模式的隱式轉換,我建議您閱讀我的博客文章 - http://maxondev.com/adapter-design-pattern-scala-implicits/ – Maxim

回答

2

是的,這是可能的。只需定義從BaseView到調用asComponent方法的Component的隱式轉換。

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

但這並不意味着這是一個好主意。 scala中的隱式轉換是一個非常強大的功能。如果一個BaseView(並通過繼承每個XXXView)是一個組件,這意味着當你想調用val myView的方法:SomeView時,你將獲得Component的所有方法。這完全混淆了命名空間,也可能是危險的,因爲您不確定是否調用了View的方法或隱式映射的Component。

在scala庫中,已經從隱式轉換轉變爲更加明確和稍微冗長的方式。以JavaConversions爲例:它們提供從scala集合到java集合的隱式轉換並返回。這聽起來像一個好主意,但也造成了很大的麻煩在實踐中:

  • 轉換髮生的事情時,你不指望他們
  • 有很多其他方法混亂的Scala集合的命名空間從Java相當於
  • 很難發現問題時,新的方法被添加到隱式轉換,在轉換

目前推薦方式的來源與方法碰撞的目標來處理與Java/Scala的集合互操作就是用更加明確的JavaConverters,它將單個方法作爲Scala添加到java集合中,並作爲Java向scala集合添加。

所以,只需保持原樣。也許將名稱更改爲.component,因爲您並不真正將轉換爲該組件的視圖,但僅允許某人以訪問每個視圖必須具有的組件。