2009-04-11 11 views
0

我想通過界面將模型與視圖配對。我想控制更新視圖的時間和頻率。所以像PropertyChangeListener這樣的東西不能很好地工作(在每個屬性設置後觸發一個事件)。GUI模式問題:PropertyChangeListener與專業視圖界面

我沒有爲特定的GUI框架開發。這裏的目標是能夠交換不同的GUI前端(現在用於測試,但稍後可能對不同版本的應用有用)。這些可能是Swing,或者它可能是一個Web瀏覽器(例如,通過GWT)。

下面是我的方法。該視圖實現了提供更新方法的界面。這是由控制器在確定完成更新模型時觸發的。對我來說,這仍然感覺很好,因爲Controller只通過模型與視圖進行交互,所以控制器不依賴於視圖的特定實現。

所以,我想我的問題(S)的

  • 做這項工作呢?
  • 這是標準做法嗎?
  • 此模式是否有名字?

粗糙的代碼示例(JAVA):

// Controller, manages Items (the model) 
class ItemList { 

    void addItem(Item item) { 
    } 

    void doStuffWithItems() { 

    // perform some set of operations, such as sorting or layout 
    for (Item item : items) { 
     // .... 
    } 

    // now with everything in it's final position: 
    for (Item item : items) { 
     item.updateView(); 
    } 
    } 
} 

// Model 
class Item { 
    private int top; 
    private int left; 
    private int width; 
    private int height; 

    // Can remember it's previous position/size: 
    public void savePostion() { 
    } 

    // And recall it for the Controller to use: 
    public public Position getSavedPosition() { 
    } 

    // Plus some other useful functions: 
    public boolean intersectsWith(Item other) { 

    } 

    public void updateView() { 
    this.view.update(); 
    } 

    void setView(ItemView view) { 
    this.view = view; 
    } 
} 

// Interface used by View implementations 
public interface ItemView { 
    // Trigger the view to reflect the current state of the model 
    void update(); 
} 

// Example, as a Swing component 
class ItemComponent extends JComponent implements ItemView { 
    private Item item; 

    public ItemComponent(Item item) { 
    this.item = item; 
    item.setView(this); 
    } 

    // ItemView#update 
    public void update() { 
    // update the component's size/position 
    setBounds(new Rectangle(item.getLeft(), item.getTop(), item.getWidth(), item.getHeight())); 
    } 

    @Override 
    public void paint(Graphics g) { 
    // ... 
    } 
} 

回答

2

我會避免強迫視圖只實現更改通知的接口。改爲在模型上創建一個單獨的「立即更新」事件。

0

模型不應直接控制或瞭解視圖。該視圖應向控制器註冊一個回調,以便控制器可以告訴視圖何時更新,這就是控制器的原因。您可以讓該模型允許modelChangedEvent的外部偵聽器。然後,視圖可以在該模型中註冊該模型,而模型不知​​道該視圖。有關MVC的信息,請參閱J2EE blueprint,以及如何在模型中發生狀態更改的間接事件通知。

0

對於在計算機桌面上運行的傳統應用程序,我推薦使用Passive View的變體。負責創建和管理表單的類是一個將事件傳遞給UI對象的瘦shell。 UI_Object通過接口與表單交互。在術語中,UI對象實現了一個UI_View接口,並將自己註冊到位於對象層次結構中較低位置的View Controller。

UI_Object然後執行修改模型的執行Command Pattern的對象。命令對象可以通過View Control公開的接口與各種視圖進行交互。

這樣做可以讓你剝離窗體類並用實現窗體接口的存根類替換它們。存根類被用於自動化測試,尤其是集成測試。

接口精確定義了Form,UI_Object,Commands和視圖之間的交互。它們可以被設計爲相對語言不可知的,因此它們可以使平臺之間的移植更容易。

你在示例中缺少的是命令對象。您在ItemViewImplementation

需要這種結構

  • ItemViewForms
  • ItemViewImplementation
  • ItemViewFormInterface
  • ItemViewCommands
  • ItemViewInterface
  • 爲MyModel

一體化ITEMLIST

ItemComponent將使用ItemViewInterface向ItemViewImplementation進行註冊。

事件的順序會是這個樣子

  • 用戶想要更新項目
  • 點擊用戶界面(假設UI 涉及用鼠標點擊)
  • 表單告訴 ItemViewImplementation通過 ItemViewInterface X使用Y參數完成了 。
  • 的ItemViewImplementation然後 創建一個命令對象,它從Y.需要 參數
  • Command對象採取在Y 參數修改模型和 然後通過 ItemViewInterface告訴
  • ItemViewImplementation更新UI。
  • ItemViewImplementation告訴 ItemViewForms通過ItemViewFormInterface更新UI 。
  • ItemViewForms更新。

這種方法的優點是每層的交互都是通過接口精確定義的。軟件操作被本地化到命令對象中。表單圖層專注於顯示結果。視圖層負責路由命令和表單之間的操作和響應。命令是修改模型的唯一東西。此外,您還可以利用「表單實現」來替換所需的任何UI,包括模擬對象以進行單元測試。