讓我們打破你的好處之一清單按一個:
- 可測性(倉庫可以被注入控制器)
這是真實的。後來在你的問題中,你說你可以輕鬆地將一個模型注入到控制器中,所以有什麼意義?關鍵在於,如果使用接口來定義存儲庫方法,則可以在生產代碼中使用具體存儲庫來實際查詢雄辯模型,同時使用實現相同接口進行測試的「僞」存儲庫。我經常這樣做,我的「假」實現只是使用一個Collection來保存我正在測試的模型。這樣,您的測試運行得更快,您不必擔心控制器測試中的遷移。它還使您不必在單元測試中與數據庫進行交互。我並不是說它對數據庫進行測試本質上是不好的,但是你應該在可能的情況下避免它。使用存儲庫可幫助您加速測試,而不需要需要與數據庫進行交互。通過在您的控制器中鍵入存儲庫接口,您可以傳入一個假實現進行測試,並將服務提供程序中的實際實現綁定到您的生產代碼。
- 抽象(複雜口才查詢可以被重構到存儲庫功能)
這是取決於你。 Laravel中存儲庫模式的問題在於,無論您嘗試多麼努力,模型都與數據庫綁定。沒有辦法繞過它。您擴展應用程序並重新使用存儲庫的機會接近於零,因此這不一定是壞事。無論如何,業務邏輯不應該在您的模型或存儲庫中,所以應用程序的核心(如果設計正確)仍然會從框架中抽象出來。在真實的存儲庫模式中,您的查詢是在存儲庫中定義的。但是由於Laravel的模型與數據庫緊密耦合,放置這個邏輯的位置並不重要。事實上,Laravel具有一些很好的雄辯功能,可能會使這種邏輯在您的模型中變得更直觀。在Laravel中,存儲庫的真正亮點就是我在第一點提出的,能夠在測試中從數據庫中進行一些抽象。
- 解耦(使我更換持久層)
這是存儲庫模式的主點和正是使得點#1可能。當然,傳遞Eloquent模型意味着無論模型在哪裏,數據庫也是如此。這只是你必須與Active Record共存的事情。
擴大對@ Lloope的回答,另一個好處是已經在一個地方定義了複雜的查詢(無論是你的模型或倉庫),以避免這樣的代碼在你的代碼庫亂丟:
$professor->getStudents()->orderBy('name')->get();
,而使用這樣的事情:
$students = $usersRepository->getStudentsForProfessor($professor, 'name', 'ASC');
與寫作各地您的應用程序雄辯查詢的問題是,隨着需求的變化,你必須更新這些查詢在您的應用程序中的任這可能只是在您的控制器中,或在您的應用程序的幾十個不同部分。一個存儲庫上的方法(或者甚至只是你的Eloquent模型)更容易維護。這意味着您的其他物體不需要擔心getStudentsForProfessor
的功能或功能。他們只知道它會爲給定的教授返回一批學生。存儲庫可以幫助您在一個地方組織查詢邏輯。一旦你定義了這個界面,或者合同,你的其他對象可以依靠它來完成它所說的事情。隨着查詢需求的變化,您可以在一個地方更新實施,而不是在您的應用中全部更新。合同仍然是一樣的。這比在任何地方編寫雄辯的查詢都有更大的靈活性。
如果您使用Eloquent,我建議您將所有數據相關邏輯放入模型中。如果你這樣做,你仍然遵循存儲庫模式,並使用存儲庫包有太多的缺點,並沒有給你任何真正重要的優勢。如果您使用的是查詢生成器或原始SQL查詢,請使用存儲庫包。 –
Repository模式將幫助您將ORM作爲一個整體進行替換,並使用其他一些OM,如Doctrine。如果您通過注入雄辯模型類來創建存儲庫,將來可以用一些其他ORM替換雄辯的ORM。但是,如果你只是想把雄辯分解成一個額外的抽象,那麼它就毫無價值,而只是一種抽象。 – webDev