Question

I aim to understand pull model MVC. I'm stuck at defining a model for a simple color-guessing game in Java Swing I chose to practice it.

I borrowed the model's initial version from an example which was very simple:

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

The initial model seems great and does the minimum necessary to play the game. With the caveat that it is the so-called push model and thus observable, so the view registers itself as an observer of the model and is notified when it changes. It is also not named properly (although I'm not sure how should I name it, I attempted to call it GameLogic).

I want to implement a pull model version of MVC, in which the View asks the model for its state in order to update itself. So I assume the model will have at least one getter for the View to retrieve that information. Actually I believe it will have more, for retrieving all the possible pieces in order to paint the choice buttons. The gameplay will become more complicated as well, I guess, with the view setting a given choice (throughout the controller) and asking the model if the game was won. A boolean check(Piece guess) method seemed more suitable but separating it into two methods void setGuess(Piece guess) and boolean won() worked better for the MVC implementation.

What would be the proper modeling for this case?

I'm stuck in one more part, which is how the View will send its position (or rather its piece or color) to the model. I'd appreciate any help on that too. Because from my understanding the view does not hold state.

This is what I came up with. I stopped using an enum (turned it into a Piece class for extensibility) and got stuck at the following model:

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

}

Was the original model okay (except for being push model MVC)? The model now seems to depend a lot on the View's requirements, this seems wrong to me. But for either push model or pull model the model will have to satisfy the View somehow.

Était-ce utile?

La solution

The only difference that there should be between the two versions of the model is the split of check() into setGuess() and won(). All the other methods you added in the pull version are either unneeded or they should have existed in the push version as well.

The fact that in the push version the View gets notified of changes in the Model does not mean that the entire state of the Model needs to be pushed. A very common implementation is that the Model only sends a notification that something has changed and the View then retrieves the information it needs from the Model in the same way as with a pull model.

And you are right that the Model in an MVC system needs to know what information may need to be presented to the user and needs to make that information available. The View only determines how the information gets presented.

Licencié sous: CC-BY-SA avec attribution
scroll top