2011-05-01 21 views
5

我正在整合Zend FrameworkDoctrine 2,我發現服務層ZF + Doctrine 2:沉重的模型類或輕量級模型+服務層?

現在我明白了(我錯了?),我有2個可能的體系:

  • 一個模式,其中類包含域邏輯,即性能+ getter/setter方法+複雜的方法
  • 輕質模型,其中類包含屬性+ getter/setter方法和服務層,含有結構域的邏輯,以及修改所述模型類

每個的優點/缺點是什麼?

把域邏輯作爲模型的外部來看,我覺得很失望,所以我不明白爲什麼要使用服務層。

+0

總有不止2種體系結構可能 – Fatmuemoo 2011-05-02 13:10:16

回答

14

什麼讓你覺得你的服務層是外部到你的模型?事實並非如此。實際上,它是您模型的核心部分,以及實體,存儲庫等。

如果您使用Doctine2,則需要服務層。一個原因是你不希望你的實體知道EntityManager(傷害可測試性)。另一個原因是你也不希望你的控制器驅動EM(這不是控制器的工作知道持久性)。

我通常使用一種架構,其中服務層是控制器與模型的接口。服務層公開了對實體進行操作的函數(或者將它們作爲參數,或者將它們返回,或者兩者兼而有之)。服務層隱藏實體的持久性。服務類驅動EM和存儲庫本身,或將其委託給控制器永遠不會知道存在的其他代碼。

所以服務層提供了一個API,控制器可以使用它來操縱業務數據。

+0

偉大而明確的答案謝謝,雖然我很難理解爲什麼丟失OOP ......我的意思是我認爲'$ user-> generatePassword()'比*更好*比'$ userService-> generatePassword($ user)'因爲該方法適用於用戶,它不是應用於參數的「函數」......這就是我所說的「外部」。對我來說,它與OOP(對象上的對象和方法)和函數編程之間的區別很相似。使用服務層,對象只是一個數據容器... – 2011-05-01 19:57:14

+0

@matthieu如果您的'generatedPassword()'方法只生成一個隨機字符串,那麼在您的實體中使用該方法是很好的;它不構成任何外部的,與持久相關的依賴關係。 – Cobby 2011-05-02 00:52:40

+1

@matthieu - 實體的*是*數據容器 - 他們只是「幻想」(因爲他們可以有方法來操縱或報告他們的內部狀態)。 generatePassword()可能沒問題 - 只要它不依賴於某些外部事物。例如,如果generatePassword()只生成8個隨機字符,並將該字符串賦值給$ this-> password(或將其傳遞給$ this-> setPassword(),然後將其合適地散列),那很好。這很好,因爲它隻影響用戶的密碼,沒有別的。現在,如果您想通過電子郵件將用戶的新密碼發送給用戶,那麼您可以在其他地方使用 – timdev 2011-05-02 05:53:53