1

MVPパターンは、ViewがPresenterにメソッドを公開することを前提としています。たとえば、Viewでは次のように書くことができます。

public HasClickhandlers getButton() {
    return myBtn;
} 

プレゼンターからこのメソッドにアクセスします。

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

しかし、このスタイルでアプリをビルドすると、不要なコードがたくさんあります。たとえば、私は作成TablesViewしたいと思いますTablesPresenter(そして、TablesPresenterそれTablesViewは最小限のエンティティ(最小限のモジュール)であり、より小さなプレゼンターとビューに分割することはできず、より複雑にすることはできません)。次に、を作成するときにTablesView、このビュー内に別のカスタムコンポーネントを配置します- MyCustomTable。そして、Inside MyCustomTableput MyCustomHeader、inside MyCustomHeaderputMyCustomFilterなど(このシーケンスははるかに長くなる可能性があります)...したがって、問題は、Presenterから入力されたテキスト(ユーザーによる)にアクセスするときに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();
}

その後、 (を含む)getFilterText()内部のメソッドを公開する必要があり、 このすべての操作の後、プレゼンターは内部のテキストにアクセスできます..そして時々このシーケンスはもっと長くなります。では、この問題を解決するにはどうすればよいでしょうか。MVPについて理解できないことがあるかもしれません。TablesViewMyCustomTableMyCustomFilter

4

2 に答える 2

2

ビューがそのコンポーネントの1つでビューを返すことができない理由はありませんが、コンポーネント化の観点から考える必要があります。カプセル化が破られ、ビューがその内部を公開します。

また、GWTでのMVPの最も重要な利点の1つは、ビューを簡単にモックし、プレゼンターを遅らせることなく単体テストできることですGWTTestCase。コードを簡単にテスト可能/モック可能にするためのトレードオフがあります。

于 2012-05-13T21:08:16.583 に答える
1

これを解決する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();
    }
}

他のコンポーネントに対しても同じことができます。

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;
    }
}

各インターフェイスで文字列のみを公開するか、クライアントコンポーネントのインターフェイス全体を公開するかを決定できます。インターフェイス全体を公開すると、プレゼンターで次のような呼び出しを行うことにより、デメテルの法則に違反する可能性があります。

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

おそらくより良い解決策は、階層の呼び出しをインターフェースに委任する文字列をインターフェースに定義することですCustomFiltergetView().getTable().getFilterText();またはeven getView().getFilterText()

インターフェイスを使用する他の利点は、プレゼンターの単体テスト用にインターフェイスを簡単にモックでき、コンポーネントを個別に表示することもでき、UIコンポーネントのさまざまな実装(たとえば、スマートフォン用に最適化されたものなど)間の切り替えを簡単に作成できることです。プレゼンターで何も変更せずに

于 2012-05-14T07:44:02.170 に答える