2012-05-13 10 views
1

MVPパターンでは、ViewからPresenterにメソッドを公開することを前提としています。MVPパターン。どのようにコードの繰り返しを減らすには?

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

のように、プレゼンターから

public HasClickhandlers getButton() { 
    return myBtn; 
} 

と、このメソッドへのアクセスをしかし、私はこのスタイルで私のアプリをビルドするとき、私はたくさんの不要なコードを持っています。たとえば、ビューでは、我々は書くことができます。たとえば、TablesViewTablesPresenterを作成したいとします(私はTablesPresenterTablesViewが最小のエンティティ(最小モジュール)であり、より小さなプレゼンターとビューに分割できず、複雑ではないと判断します)。次に、TablesViewを作成すると、別のカスタムコンポーネント - MyCustomTableが表示されます。内MyCustomTableMyCustomHeaderを入れてMyCustomHeaderを入力してくださいMyCustomFilterなど... MyCustomFilterの中にPresenterから(ユーザーが入力した)テキストにアクセスしたい場合は、メソッドを公開する必要がありますMyCustomFilterに: - :MyCustomTableの内側に私が必要、それの後に

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

MyCustomFilterが含まれているウィジェットで、その後

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

すなわちMyCustomHeaderに私はこの方法を公開する必要がありますこの方法公開する:それは後

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

を私はTablesViewgetFilterText()方法を公開する必要があります(つまり、MyCustomTableが含まれている)と、このすべての操作の後に私のプレゼンターは、内部MyCustomFilterをテキストにアクセスすることができます...そしていつかこのシーケンスは、より長いです。 この問題を解決するにはどうすればよいですか? MVPに関するいくつかのことを理解できないことがありますか?

+0

質問を変更してください。それは混沌としているし、あまりにも多くの詳細が含まれています。 – dzendras

答えて

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

あなたが他の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; 
    } 
} 

Y各インタフェースで文字列またはクライアントコンポーネントのインタフェース全体だけを公開するかどうかを決定できます。あなたは全体のインターフェイスを公開する場合は、あなたのプレゼンターで、このような呼び出しを持つことによってlaw of demeterに違反する可能性があります

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

おそらくより良い解決策は、デリゲートの呼び出しまでごCustomFilterの階層あなたのインタフェース内の文字列を定義することですインタフェース:getView().getTable().getFilterText();またはeven getView().getFilterText()

インターフェイスを使用することの他のメリットは、プレゼンターの単体テストを簡単にモックでき、コンポーネントを単独で表示したり、UIコンポーネントのさまざまな実装間でスイッチを簡単に作成できることです。スマートフォンなど)を変更することはありません。

2

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

また、GWTのMVPの最も重要な利点の1つは、遅いGWTTestCaseではなく、あなたの意見を簡単に嘲笑してプレゼンターをユニットテストできるということです。あなたのコードを簡単にテスト可能/モック可能にするためのトレードオフがあります。

+0

ありがとうございますので、あなたが私がカスタムコンポーネント全体を返すメソッドを公開することを提案します。例えば 'public' MyCustomHeader getHeader()' public 'getFilterText(){return myCustomHeader.getFilterText() )}? – MyTitle

+0

あなたは '' MyCustomHeader''を公開することができますが、あなたの '' MyCustomHeader'' UIコンポーネントと '' Presenter''の間に緊密な結合を作り、あなたはおそらく '' MyCustomHeader''コンポーネント全体を模擬して使用する必要がありますJUnitテスト。さらに、後であなたが '' MyCustomHeader''を別の実装にすることを決めた場合、タブレットや携帯電話は問題に遭遇します。 代わりに、 '' Presenter''から呼び出したいすべての関数を公開する '' MyCustomHeader'' UIコンポーネント用のインタフェースを作成することができます。 –

+0

@Ümit、ありがとう。だから要約しましょう。まず、私のビューや他のカスタムUIコンポーネント(他のカスタムウィジェットが含まれています)の中に、格納可能なコンポーネントのメソッドにアクセスするメソッドだけでなく、格納可能なコンポーネント全体にアクセスするメソッドを公開する必要があります。 2番目:すべてのカスタムコンポーネントにインターフェイスを使用するほうが、実現しない方が良いです。 – MyTitle

関連する問題