2015-04-19 48 views
0

這個問題與Java DAO模式的核心理解有關。請看一個簡單的java dao pattern example來理解我的問題。在同一個JVM上實現Java DAO模式

在下面的第2行,學生對象已被更改爲新名稱,如果客戶端和後端都在相同的JVM下運行,那麼第三行的要點是什麼?

在我對DAO模式的簡單理解中,客戶端必須只使用服務來更改數據,例如下面的studentDao,並且客戶端不應該有直接更改值對象(pojo)的可能性。但是,當客戶端和後端服務都在同一個JVM下運行時,並且客戶端使用普通的setter來獲得POJO時,爲什麼客戶端需要調用該服務?

是否有任何最佳實踐來實現DAO模式,其中客戶端可以並且必須僅使用dao-services來消費/更改數據?一個很好的例子將是很好的看看。

//update student 
1. Student student =studentDao.getAllStudents().get(0); 
2. student.setName("Michael"); 
3. studentDao.updateStudent(student); 

回答

0

好吧,它在同一個JVM上意味着什麼。如果您的DAO使用數據庫,那麼當您更改POJO時,對象不會在數據庫中更改。同樣,當其他線程將加載相同的實體時,將根據數據庫內容創建新的POJO(除非您的DAO進行一些特殊的緩存)=>沒有問題。

因此,現在讓我們假設您構建了某種內存中的DAO。如果執行不當,在這種情況下,POJO上的更改可能會「影響」其他客戶端,正如您已經指出的那樣。然而,這不是DAO的實施 - 所以你必須小心,客戶可以訪問的POJO不能影響DAO「狀態」。最簡單的方法是返回defensive copies,既返回所有值,也返回所有輸入(插入,更新等)。

+0

是的,通過「相同的JVM」,我實際上是你指出的;只有該對象的單一表示形式,並且任何引用它的人都可以改變它。在這個例子中,創建一個名爲StudentDTO的重複類是不是一個好主意,而不需要服務studentDao發送給客戶端的setter方法? – Moni

+0

但DAO模式並不指示無法更改實體對象。唯一的一點是,「持久表示」不能在DAO之外改變。在你的例子中,Student對象可以用setter來改變。然而,對防禦性副本的替代方法是使用不可變的對象。 – sodik

+0

是的,不可改變的對象是更喜歡的,但大多數時候我們需要setter在一生中改變對象的狀態。所以我喜歡防禦性拷貝或對象深層拷貝的方法,比如使用拷貝構造函數。然後客戶端可以調用setter來更改對象,但必須使用DAO服務來實際更改原始對象。如果你喜歡不可變的對象,可以使用 – Moni