2012-02-18 45 views
1

我有一個Java應用程序,其中域控制器與UI分離。問題是這些控制器可以返回域對象,並且可以將域對象作爲參數。製作不可修改的對象

其中一些返回的域對象是可變的,這就是我想要阻止的。我希望UI(或未來的UI)無法直接修改域而不訪問控制器。

我嘗試了兩種選擇:

  • 在我確信,每個類實現的「不可修改的」 接口只含有干將第一個。如果我需要返回一個對象到UI,我返回了它的'Unmodifiable'接口。這樣UI才能查看獲取者。 這個問題,他們仍然可以很容易地轉換到原始對象和訪問獲得。起初,我認爲這種安全水平足夠好,但事情發生了,有人不小心鑄造了一些物體,並以不正確的方式使用它們,並破壞了完整性。

  • 在第二個我試圖提供不可修改的包裝爲每個可能返回的對象。但問題是這些返回的對象可以用作控制器中方法的參數,因此它們需要在控制器中解包。我試圖製作uwrap()方法包 - 私有,但是我必須將每個特定的包裝類與控制器放在同一個包中,這有點不方便。

編輯:3TH選項:

  • (與感謝vic)在第三選項的目的是通過一種不可修改包裝包裹,但不能被此包裝包裝除去。每個Unmodifiable都鏈接到它在Hashmap中的可修改對象。所以'解包'是通過獲取鏈接到不可修改對象的可修改對象來完成的。

有誰知道或有如何使物體不可修改,使他們能夠通過控制器返回,並有可能使他們再次修改的時候都回傳給控制器的一些想法?

+0

如果你使參數最終? – 2012-02-18 14:10:49

+0

有些參數不能是最終的,因爲它們需要在域邏輯中進行更改。 – Xochipilli 2012-02-18 14:17:36

回答

2

如果控制器私下存儲對象的可變版本並將其不可變版本返回到「外部世界」會怎麼樣?可變版本將有一些獨特的ID,並且控制器將能夠通過在某種Collection中查找它而得到unwrap

+0

我在想我自己,這是目前在我的名單上! 唯一的ID可以是對象的哈希碼,然後可以使用HashMap作爲集合。 – Xochipilli 2012-02-18 14:48:40

+1

如果你走這條路,注意內存泄漏!散列表中的任何元素都不符合GC的條件。 'WeakHashMap'會有所幫助,但這種方法需要一些關於對象生命週期的手勢(我通常對WeakReference或WeakHashMap持謹慎態度 - 對我來說似乎是一個柺杖)。 – yshavit 2012-02-18 15:17:21

+0

@yshavit我想到了這個問題,但我不知道WeakHashMap,感謝提示,我研究它。 – Xochipilli 2012-02-18 15:29:32

2

尋找State設計模式,這是一個很好的選擇來表示一個對象的狀態。

基本上,無論何時UI想要顯示一個域對象,控制器都會給它一個不可變的DTO對象來表示對象本身的快照。這將限制UI層僅擁有您的域對象的不可變的快照。當UI想要更改域對象時,它會向控制器發送不可變狀態對象,以便在內部修改相應的域對象。

+0

但我不想使用不可變的快照。我喜歡使用不可修改的對象,這些對象仍然可以通過域邏輯進行更改,但不能由用戶更改。 對於不可修改對象的持有者而言,可以通過域邏輯進行更改。 – Xochipilli 2012-02-18 15:02:19

+0

@Xochipilli您可以隨時檢查域對象的每種方法。如果調用者沒有足夠的權限調用該方法,該檢查將拋出異常。 – GETah 2012-02-18 15:11:11

+0

我曾考慮過這個問題,但我很快放棄了這個想法,因爲它似乎有很多工作。 不好的java沒有朋友類:( – Xochipilli 2012-02-18 15:24:06