4

MVP を学習しようとしていますが、何かがわかりません。プレゼンターがビューをインターフェイスとして使用する場合、ビューは単なるコントロールのレンダリングではありません。単語が UI にランダムに生成され、ユーザーが画面に落ちてくる単語を入力しなければならないタイピング練習ゲームを作成しようとすることを想像してみてください。

したがって、ビューには次のようなメソッドがあります。

public interface View {
    addWord(String word, double x, double y); // or possibly (Word word)
    moveWord(String word, double distance);
    removeWord(String word);
    setScore(int score);
    registerKeyListener(KeyListener listener);
    // other stuff
}

しかし、最終的には VIEW がカスタム コントロールの作成を担当する必要があります。ここでは多くのコードが省略されていますが、私の言いたいことを説明するにはこれで十分だと思います。例:

public class SwingView {
    private JPanel thePanel;

    private Map<String, WordComponent> currentWords = new HashMap<>();

    public SwingView() {
        thePanel = new JPanel(new WordLayout());
        // other stuff
    }

    public void addWord(String word, double x, double y) {
        WordComponent newWord = new WordComponent(word);
        currentWords.put(word, newWord);
        Point2D.Double point = new Point2D.Double(x, y);
        thePanel.add(newWord, point);
    }

    public void removeWord(String word) {
        WordComponent theWord = currentWords.get(theWord);
        thePanel.remove(theWord);
    }
}

すでにビューの実装にはロジックが進行中です。を維持していMapますWordComponentWordLayout implements LayoutManager2ここには、 との 2 つの独自のクラスがありますWordComponent extends JLabel(または他の何かですが、それはさらに多くのコードになります)。

理論的には、プレゼンターは Swing について何も知らないはずなので、コンソールなどにログを記録するモックを使用して単体テストを行うことができます。しかし、単に Swing オブジェクトを管理すること自体が仕事です。または、このアプリケーションを Tomcat Web ページに変換したい場合はどうでしょうか。現在、クラスServletViewは単語を移動する AJAX 呼び出しを管理しています。これは AJAX フレームワークに依存しており、より多くの作業がView.

概要:View実装には、独自のコンポーネントを管理する「ロジック」が必要ですか?

フォローアップ: 上記のコードはおそらく応答しないでしょう。なぜなら、ModelPresenterはイベント ディスパッチ スレッドで動作していないからです (または、動作していて、おそらくもっと悪いことです)。表示の更新をイベント ディスパッチ スレッドに渡すコードはどこに行くのですか? または、Presenterイベント ディスパッチ スレッドにある必要がありますか?

編集: 1つのアイデアが思い浮かびました。Swing を使用しているかどうかなど、実装の詳細を認識しているプラ​​ットフォーム固有のサブプレゼンターを用意します。

Edit2: @DuncanJones の回答に基づく、さらに別の質問。ゲームをサイズ変更可能にし、新しいサイズに基づいてすべてのサイズをスケーリングするロジックを配置したいと想像してください。そのロジックはView、または にありPresenterますか?

4

2 に答える 2

4

View コンポーネントには、ユーザーにインターフェイスを表示するための十分なロジックが含まれている必要があります。使用するフレームワークによっては、ビューにかなりの量のコードが含まれる場合があります。重要なことは、ビジネス ロジックがプレゼンターにあることを確認することです。

2 番目のクエリに関しては、すべてのプレゼンター メソッドは、ビューが呼び出したときに EDT で呼び出されます (Swing の場合)。プレゼンターが必要とするアクションが些細なものでない限り、私はすぐにバックグラウンド スレッドを開始して作業を完了します。を使用して完了すると、そのスレッドはビューを更新しますSwingUtilities.invokeLater()

実際、Swing に縛られないようにするために、私は自分のEventDispatcherクラスを各プレゼンターに渡す傾向があります。これは、 と同じメソッドを持つインターフェイスSwingUtilitiesです。その後、必要に応じて別のクラスで代用できます。

補足: これにより、JUnit を使用した Presenter の単体テストが困難になる可能性があります。これは、Presenter メソッド (および単体テスト) がバックグラウンド スレッドよりも先に完了するためです。Executorバックグラウンド スレッドの実行を担当する を使用して、各プレゼンターを作成する傾向があります。次に、単体テスト環境で、同じスレッドでメソッドExecutorをすぐに実行する特別な実装を渡します。run()これにより、単体テストがシングル スレッドであることが保証されます。例:

public class SingleThreadExecutor implements Executor {
  @Override
  public void execute(Runnable command) {
    command.run();
  }
}
于 2013-07-24T14:20:06.147 に答える