2012-05-13 59 views
1

MVP模式假定View將方法暴露給Presenter。例如,在查看我們可以這樣寫:MVP模式。如何減少代碼重複?

public HasClickhandlers getButton() { 
    return myBtn; 
} 

,並獲得從發言這種方法,像

view.getButton().addclickhanlder() ... 

但是當我建立我的應用程序在這種風格,我有很多不必要的代碼。例如,我想創建TablesViewTablesPresenter(我決定TablesPresenterTablesView是最小的實體(最小模塊),不能分成更多的小型演示者和視圖,並且不能更復雜)。然後,當我創建TablesView時,我想在此視圖中放入另一個自定義組件 - MyCustomTable。而且裏面MyCustomTableMyCustomHeader,裏面放MyCustomHeaderMyCustomFilter等(這個順序可能更長)... 所以問題是,當我想從發言者訪問到內部MyCustomFilter輸入的文本(用戶),我需要公開的方法在MyCustomFilter

//inside MyCustomFilter 
public String getFilterText() { 
    return textBox.getText(); 
} 

然後在含有小部件MyCustomFilter - 即MyCustomHeader我需要公開這個方法:

//inside MyCustomHeader 
public String getFilterText() { 
    return myCustomFilter.getFilterText(); 
} 

後,裏面MyCustomTable我需要揭露這個方法:

//inside MyCustomTable 
public String getFilterText() { 
    return myCustomHeader.getFilterText(); 
} 

它後,我需要公開內部TablesViewgetFilterText()方法(包含MyCustomTable)而這一切的操作後,我的演講能夠訪問到文本中MyCustomFilter。而有時這個序列是比較長。 那麼如何解決這個問題呢?可能我對MVP有些不瞭解嗎?

+0

改說你的問題。這是混亂的,包含了太多的細節。 – dzendras

回答

1

解決這個問題的一種方法是使用接口。通過這種方式,您可以暴露組件的視圖,而不會在視圖和演示者之間建立緊密的耦合。沿着這些線路

東西:

public interface CustomFilter { 
    String getFilterText(); 
    // other methods that might be accessed from your presenter 
} 

public class MyCustomFilter implements CustomFilter { 

    @Override 
    public String getFilterText() { 
     return textBox.getText(); 
    } 
} 

你可以做同樣的事情在其他componenents:

CustomHeader:

public interface CustomHeader { 
    CustomFilter getFilter(); 
    // or String getFilterText() 
    // other methods that might be accessed from your presenter 
} 

public class MyCustomHeader implements CustomHeader { 

    @Override 
    public CustomFilter getFilter() { 
     return myCustomFilter; 
    } 
} 

CustomTable:

public interface CustomTable { 
    CustomHeader getHeader(); 
    // or Sring getFilterText(); 
    // other methods that might be accessed from your presenter 
} 

public class MyCustomTable implements CustomTable { 

    @Override 
    public CustomHeader getHeader() { 
     return myCustomHeader; 
    } 
} 

ÿ您可以決定是否只想在每個接口中公開一個字符串或整個客戶端組件的接口。如果你暴露了整個界面,你可以通過在你的演講是這樣的呼叫違反law of demeter

getView().getTable().getHeader().getFilter().getFilterText(). 

可能是一個更好的解決辦法是在你的接口來定義字符串,其委託的調用了層次下達給您CustomFilter接口:getView().getTable().getFilterText();even getView().getFilterText()

使用接口的其他好處是,您可以輕鬆地對它們進行模擬,以便單元測試演示者,甚至可以孤立地查看組件,並且可以輕鬆地在UI組件的不同實現之間創建切換(例如,針對智能手機等)而不會改變演示者中的任何東西

2

沒有理由你的看法不能在其組成部分之一返回視圖,但你必須想組件化方面:那會打破封裝,你的看法則暴露了其內部結構。

另外,請記住,在GWT中MVP最重要的好處之一是,您可以輕鬆地嘲笑您的觀點並單元測試您的演示者,而不會出現緩慢的GWTTestCase。有一些權衡使你的代碼易於測試/可嘲弄。

+0

謝謝,所以你建議我公開返回整個自定義組件的方法(如你寫的 - 整個'view'),例如:'public MyCustomHeader getHeader()'而不是返回public String getFilterText(){return myCustomHeader.getFilterText )}? – MyTitle

+0

那麼你可以公開你的''MyCustomHeader'',但是你會在你的''MyCustomHeader'' UI組件和你的'Presenter'之間建立一個緊密的耦合,你可能不得不嘲笑整個''MyCustomHeader''組件JUnit測試。此外,如果您稍後決定對您的''MyCustomHeader''進行不同的實現以獲得平板電腦或移動設備,則會遇到問題。 相反,您可以爲您的''MyCustomHeader''用戶界面組件創建一個接口,該接口公開您想要從''Presenter''調用的所有函數。 –

+0

@Ümit,謝謝。所以讓我們總結一下。首先:在我的視圖和其他不重要的自定義UI組件(其中包含其他自定義小部件)內我需要公開訪問整個可容納組件的方法,而不僅僅是訪問可容納組件方法的方法。第二:最好對所有自定義組件使用接口,而不是實現它們。 – MyTitle