web-dev-qa-db-ja.com

この場合、MVCモデルを適切にモデル化するにはどうすればよいですか?

私は理解することを目指していますプルモデル MVC。 Java Swingでシンプルなカラー推測ゲームのモデルを定義することにこだわっています。Swingで実践しました。

私は非常に簡単な例からモデルの初期バージョンを借りました:

_class Model extends Observable {

    private static final Random rnd = new Random();
    private static final Piece[] pieces = Piece.values();
    private Piece hidden = init();

    private Piece init() {
        return pieces[rnd.nextInt(pieces.length)];
    }

    public void reset() {
        hidden = init();
        setChanged();
        notifyObservers();
    }

    public void check(Piece guess) {
        setChanged();
        notifyObservers(guess.equals(hidden));
    }
}

enum Piece {

    Red(Color.red), Green(Color.green), Blue(Color.blue);
    public Color color;

    private Piece(Color color) {
        this.color = color;
    }
}
_

最初のモデルは素晴らしいようで、ゲームをプレイするために必要な最小限のことを行います。これはいわゆるPushモデルであり、したがって監視可能であるという警告があるため、ビューはそれ自体をモデルのオブザーバーとして登録し、変更時に通知されます。また、適切に名前が付けられていません(どのように名前を付ければよいかわかりませんが、GameLogicと呼んでみました)。

私はpullモデルバージョンのMVCを実装したいと思います。この場合、ビューはモデルに自身の状態を更新するように要求します。したがって、モデルには、ビューがその情報を取得するための少なくとも1つのゲッターがあると想定しています。実際には、選択肢ボタンをペイントするためにすべての可能なピースを取得するために、それはもっとあると思います。ビューは特定の選択肢を(コントローラー全体で)設定し、ゲームに勝利したかどうかをモデルに尋ねるので、ゲームプレイもより複雑になると思います。 boolean check(Piece guess)メソッドの方が適しているように見えましたが、2つのメソッドvoid setGuess(Piece guess)boolean won()に分離すると、MVC実装の方がうまく機能しました。

この場合の適切なモデリングは何でしょうか?

ビューがその位置(またはそのピースや色)をモデルに送信する方法がもう1つあります。それについても助けていただければ幸いです。私の理解から、見解は国家を保持しないからです。

これが私が思いついたものです。私はenumの使用を中止し(拡張性のためにPieceクラスに変更しました)、次のモデルに行き詰まりました。

_public class GameLogic {

    private static final Random RANDOM_NUMBER_GENERATOR = new Random();
    private final Piece [] pieces;
    private Piece hidden = createRandomPiece();
    private Piece guess = null;

    public GameLogic(Piece [] pieces) {
        this.pieces = Objects.requireNonNull(pieces);
    }

    private Piece createRandomPiece() {
        return pieces[RANDOM_NUMBER_GENERATOR.nextInt(pieces.length)];
    }

    public void reset() {
        hidden = createRandomPiece();
    }

    public Piece getGuess() {
        return guess;
    }

    public Piece [] getPieces() {
        return Arrays.copyOf(pieces, pieces.length);
    }

    public void setGuess(Piece guess) {
        this.guess = guess;
    }

    public boolean won() {
        return guess.equals(hidden);
    }

    public Piece getPieceAtPosition(int position) {
        if (position < 0 || position >= pieces.length) {
            return null;
        }

        return pieces[position];
    }

}
_

元のモデルは大丈夫でしたか(プッシュモデル MVCであることを除いて)?モデルは現在ビューの要件に大きく依存しているようですが、これは私には間違っているようです。ただし、プッシュモデルまたはプルモデルの場合、モデルはビューを何らかの方法で満たす必要があります。

2
Piovezan

モデルの2つのバージョンの間にあるべき唯一の違いは、check()setGuess()won()に分割されていることです。プルバージョンに追加した他のすべてのメソッドは不要であるか、プッシュバージョンにも存在しているはずです。

プッシュバージョンでは、ビューがモデルの変更を通知されるという事実は、モデルの状態全体をプッシュする必要があることを意味しません。非常に一般的な実装では、モデルは何かが変更されたという通知のみを送信し、ビューはプルモデルの場合と同じ方法で必要な情報をモデルから取得します。

また、MVCシステムのモデルは、ユーザーに提示する必要のある情報を把握し、その情報を利用可能にする必要があることは間違いありません。ビューはhowのみを決定し、情報が表示されます。