2013-03-08 34 views
7

我想在swing應用程序中應用MVC模式。不過,由於您嵌套了面板的層次結構,因此我面臨兩個主要問題。父母 - >孩子 - >大孩子 - >大孩子。Swing MVC - 事件傳播和數據共享

問題1:如何在控制器和視圖之間傳輸數據?如果我將數據從父母傳遞給孩子,那麼會有很多重複,如果我更換了一個孩子,所有父母都需要更改。我不希望視圖直接訪問數據庫中的數據,我希望通過控制器將數據傳輸到視圖。

問題2:如何在這樣的層次中將視圖中的事件傳播到控制器? 我正在考慮使用PropertyChangeListener。如果控制器必須採取任何行動,則查看將會發生firePropertyChange事件。控制器將監聽這些事件並執行一些操作。但是,如果我這樣做的層次結構,那麼會出現代碼重複。

我有三個想法,可能是有用的:

  1. 要使用控制器每個面板,但這種以這種方式我將結束與很多控制器。
  2. 使用Mediator設計模式,它將提供視圖和控制器之間的通信。
  3. 使用中央接收器&通知程序將偵聽來自視圖的所有屬性更改事件並通知感興趣的控制器。但這隻會解決我的第二個問題:

請參考下圖有一個第三個想法的圖片。如果是第二個,Mediator將進入中心。

請評估並讓我知道是否有人以更好的方式實現了這樣的問題。

enter image description here

+2

Marting Fowler發表了一系列有關演示架構的文章(沒有任何鏈接方便,對不起,但應該出現在搜索頂端附近:-) – kleopatra 2013-03-17 12:40:29

+0

引用了一些_model-view-presenter_(MVP)鏈接[這裏](http://stackoverflow.com/a/15181906/230513)。 – trashgod 2013-03-18 02:32:31

回答

1

我有一個建議對您的問題1:

你可以有一個包含另一個視圖模型的特性的視圖模型。而在你的控制器方法上,你只需要接收父視圖模型,因爲模型聯編程序會爲你綁定所有的屬性。

public class GrandChildViewModel{ 
    public Int32 SelectedDropDownItem { get; set; } 
    public List<Foo> ListOfFoo { get; set; } 
} 

public class ChildViewModel{ 
    public String Name { get; set; } 
    public Int32 Age { get; set; } 
} 
public class FatherViewModel{ 
    public ChildViewModel Child { get; set; } 
    public GrandChildViewModel GrandChild { get; set; } 
} 

這是層次結構的一個例子。您的視圖只會引用FatherViewModel。你的控制器也會收到FatherViewModel。 的模型綁定器會自動完成自己的工作,如果你創建的HTML類似:

@Html.TextBoxFor(m => m.Child.Name) 

,它將使輸入:

<input type="text" id="Child_Name" name="Child_Name" /> 
+0

對不起,但我沒有得到你的解釋。你可以請直接給我一些相同的參考或鏈接? – Atul 2013-03-19 05:38:39

+0

這裏的鏈接,有一個viewModel答案包含另一個ViewModel:http://stackoverflow.com/questions/3267015/model-binding-for-a-a-viewmodel-containing-multiple-objects – TiagoBrenck 2013-03-19 11:03:30

+0

這個想法是代表你的層次結構到視圖模型中,並創建一個成爲所有其他視圖模型的「父」,包含所有其他視圖模型的屬性。該「父親」將負責轉移視圖中更改或鍵入的所有信息。 – TiagoBrenck 2013-03-19 11:06:54

1

問題1:如何控制器和視圖之間傳輸數據當你有 有這樣的層次?如果我將數據從父母傳遞給孩子,那麼 會有很多重複,如果我更換了一個孩子,所有父母都需要更改。我不希望視圖直接訪問數據庫中的 數據,我希望僅通過 控制器將數據傳輸到視圖。

如何忽略層次結構並通過向相關控制器註冊視圖來採用更線性的方法?數據可以通過模型獲得,其中可以通過ObserverListener模式觸發更改。

有了這個,你不會有任何重複發生。一切都將集中在一個模型或一系列模型中。在發生用戶操作或外部事件後,控制器或控制器可以在註冊視圖列表上運行通知。

此外,視圖應該不會像你說的那樣訪問數據源。這裏應該至少有一個抽象層。如果您的控制器使用中介模式,我會做的是通過將請求轉發到額外數據層中的接口來處理此事。

進一步思考,我不認爲如果將已註冊通過視圖做一個好主意。所以我會保持分開。手動初始化視圖或找到一種方法遍歷所需的視圖。也許通過一種使這一步自動化的工廠來獲得你的觀點。

問題2:如何在這樣的 層次結構中將事件從視圖傳播到控制器?我正在考慮使用PropertyChangeListener。如果控制器需要採取任何措施,將會查看 firePropertyChange事件。 控制器將監聽這些事件並執行一些操作。但 再次如果我這樣做的層次結構,那麼會有代碼重複。

同樣,你可以通過一個線性方法。當一個視圖被註冊時,Controller可以添加它的監聽器。或者你可以讓視圖發送一些可以通過調度機制處理的語義風格消息(例如:doAction(「Save」))。會讓你決定如何轉發參數。

是否需要PropertyChangeListeners?我的意思是,你需要那種粒度嗎?

我有三個想法,可能是有用的:

要使用控制器每個面板,但這種以這種方式我會在最後 有很多的控制器。使用Mediator設計模式,將提供視圖和控制器之間的通信。使用中央 收件人&通知程序將從視圖中監聽所有屬性更改事件 ,並通知有興趣的控制器。但這 只能解決我的第二個問題:

這聽起來像隱約HMVC。通過這種方法,您可以爲每個子系統提供三元組模型視圖控制器。這是一個有趣的想法,但可能很混亂,不清楚應該如何解決層次結構以及協調/從屬關係如何實現。

也許你可以有第四個中性類應用的每個模塊/子系統在那裏你可以插入一個視圖,模型和控制器,如果他們中的一個缺失或不正確引發的異常。

或者,下面的這個想法中央通知的,你可以有作爲一個路由機制等特定功能的控制器或多個基本動作的中央控制器。如何將消息轉發給這些取決於你。由於集中化將使這個類的設計變得必不可少,所以請小心線程。

無論你做什麼,儘量讓事情儘可能簡單。您應該可以在模型和控制器上進行測試,而不必大驚小怪。

+0

感謝您的意見。我也考慮爲每個視圖(面板)創建一個控制器,但正如我所提到的,這樣我將以很多控制器結束。現在,一個對話框包含一個TabbedPane,它有兩個子TabbedPane和6-8個JPanel。如果我這樣走,至少會有10個控制器。而且,將來,我可能需要添加額外的視圖和控制器以滿足其他要求。 – Atul 2013-03-19 06:16:29

+0

TabbedPane的使用表明這些面板是相關的,因此如何使用控制器和/或模型。無論如何您應該集中管理,以便監控應用程序中發生的事情。例如,想象一下如果你必須添加一個權限系統。對多個班級進行全系統變革將是乏味的。所以它似乎是一個很好的解決方案。 – 2013-03-19 11:59:36

+1

我想,我會保持這種方式到現在爲止。讓我們看看它是如何。感謝您的建議。賞金是你的幫助:) – Atul 2013-03-20 01:27:35

1

當我結束使用 this HMVC Pattern時,我遇到了類似的問題。是的,你是對的,因爲會有很多控制器。但是,它確實會爲您提供清晰的代碼問題分離。您可以通過創建一些特定於應用程序的高級複合小部件來限制控制器的數量。在這種情況下,層次結構最多可以限制在2層或3層,並且可以將控制器鏈接爲將事件委託給任何父/子。

一旦你從服務器加載數據,你也可以保持會話映射,以獲得一些緩解有快速和easy access to frequently required data - 但我不喜歡它太多。

如果開發團隊正確理解並遵循它,該模式運行良好。