2015-01-26 107 views
0

我喜歡將Spring添加到我的Scala項目中以用於教育目的。但我不明白Spring Scala的優勢在於解耦組件。如何使用spring scala來解耦?

我創建了一個簡單的配置:

import org.springframework.scala.context.function.FunctionalConfiguration 

class Configuration extends FunctionalConfiguration { 
    bean() { 
    new Service() 
    } 
} 

和一個簡單的服務:

class Service { 
    def method = "Bonjour tout le monde!" 
} 

,然後一個應用程序,它同時使用:

import org.springframework.scala.context.function.FunctionalConfigApplicationContext 

object Application extends App { 
    implicit val context = FunctionalConfigApplicationContext(classOf[Configuration]) 

    val service = context.getBean(classOf[Service]) 
    println(service.method) 
} 

這只是我的解釋和Spring Scala示例的實現。

我的應用程序仍然具有Service類的知識。我只能寫:

val service = new Service() // instead of asking for a Bean which has classname Service 
println(service.method) 

具有相同的效果。

我錯過了什麼嗎?

+0

我明白,並試圖改變,如果bean(「sophisticatedService」){...}是可能的,並且用於文本定義bean,然後使用:context.getBean(「sophisticatedService」)。由於它現在被文本名稱解耦。 – springScala 2015-01-26 22:06:05

+0

Spring對我來說真正解決的唯一問題是循環依賴。但後來我轉向使用惰性vals(以避免null),並在構造函數中通過名稱傳入注入參數。所以,不要再使用Spring IoC了。有些人喜歡'@ Autowired'這個東西,但是你可以使用traits(在trait裏面定義依賴關係,並將它混合到已經定義了這個依賴關係的上下文中) - 更多地使用google搜索'Cake pattern' – dk14 2015-01-27 01:01:10

+0

你可以使用spring你有服務和幾個實現的接口,例如你的應用程序將依賴於UserRepository。您可以使用FileUserRepository實現,並且您的應用程序完全與該細節分離。稍後,您可以實現DatabaseUserRepository並切換實現,而無需觸及代碼,或者您可以使用mock進行測試,並仍然依賴於UserRepository保持不變的代碼。 – chalimartines 2015-01-27 03:43:53

回答

0

這確實將您對Service的使用從實例化中分離出來。例如。如果將來Service更改取決於其他一些InnerService,或者由於某種原因而在構造函數中無法完成一些初始化,但在使用它之前需要在方法調用中發生(.connectToDatabase()等),或者如果您如果你對編程的接口,而不是實現,如

val service = context.getBean(classOf[Service]) 
println(service.method) 

:想用一個模擬測試,以取代Service,那麼你就可以做到這一點沒有改變這兩行代碼

trait IService { 
    def method: String 
} 
class Service extends IService... 

val service = context.getBean(classOf[IService]) 

那麼你也做,就容易掉出Service對於不同的實現,雖然給出額外的代碼行,我可能不會理會這樣做,直到我其實有一個以上的實施。我不確定Spring是否有自己的重量(這是一個非常龐大而複雜的庫),特別是在它的更簡潔的構造函數語法的Scala中。但是,不管你是否使用Spring,都值得將你的依賴關係的構建與應用程序的「接線」與實際使用分開。使用Service的IMO類Foo應該明確地通過它的構造函數class Foo(service: Service)接受它,並將Service的構造/初始化保留爲專用於該類的類/函數。