MVC understanding

Started by
19 comments, last by Kylotan 7 years, 6 months ago

Hey guys. I've some problems with understanding MVC.

I mean I know that Model stores data, Controller changes that data according to user input, and when changes happen, Model dispatches event, so View could catch it and render representation. But how do I suppose to arrange all that stuff? Do I need some kind of container class, which contains all in one Model, View and Controller? And most important: how do I build hierarchy with this? I've read about HMVC, but there's no answers too.

For example, I'm trying to make a tic-tac-toe game, and I have Game, which contains two Players, and Board.

Game has it's Model, View and Controller

GameModel contains two Players and Board

GameView represents two Players and Board

GameController responsible for taking turn.

Player has it's Model, View and Controller

PlayerModel contains state (active/inactive)

PlayerView represents Player screen

PlayerController implements logic (human/computer)

Board has it's Model, View and Controller

BoardModel contains cells

BoardView represent cells

BoardController mark cells (X/O)

MVC should help to organize code, but for now it turned my code into complete mess.

I've got my project here https://github.com/FennecFix/tictactoe

It would be so nice, if you help me organize my code correctly

Advertisement

MVC was designed for user interfaces, so you should be careful in how you apply it. You certainly don't need a Model, View, and Controller class for each concept in your game.

For tic-tac-toe I would just have this:

Model classes: Game, Board, Player. Game owns board and players.

View classes: GameView, BoardView. Each view class references the relevant model class. GameView also owns BoardView.

Controller classes: GameController. This takes input and calls the relevant functions on the game. You don't really need controllers for each player or the board.

Yeah, as Kylotan said, I could see having two instances of a PlayerController, one for each player, but not strictly necessary in a turn based game. As for tying things together, I like event systems for MVC or MVVM. So the input/controller changes the model, and then the model raises an event that it's data changed, and the view, which has subscribed to that event, receives the event and updates itself accordingly.

Concrete example: "Players clicks the left mouse button on the mouse" --> Controller receives that input, translates it into which square was clicked on, and changes the model, which then raises the event for the view. (Though I have no qualms with the controller also raising events, like for the instance where the user clicked on an invalid square, no data has changed, but you still probably want to play a noise or have the view react in some way)

MVC should help to organize code, but for now it turned my code into complete mess.

When you get into design patterns in general (of which MVC is just one of many), then you need to quickly learn that design patterns aren't applicable everywhere, they don't have to be implemented exactly as described, and they aren't legos that you build with (they are shorthands you use to describe concepts).

What this means is:

A) Is this the appropriate place to use MVC?

B) What is the best way to implement it in this situation?

C) Are you using it just because you've heard about MVC, or are you using it because you have a genuine need for MVC?

Also, MVC is primarily about separation of concerns, not necessarily code organization.

Some people implement MVC as a View, with the Model also being the Controller. Sometimes the Model and the View are both controllers. There are other good implementations too. It's important to realize that different projects have different needs, and there's not "One True Implementation" that solves everything for every problem.

Often, you don't need to pass messages to the View, just give the View a pointer/reference to the Model, otherwise you'll be duplicating the same data in two different locations.

I would argue that, in this situation, making 'Game' have separate Model, View, and Controller is overkill. With Player is could be overkill, but might not be. With Board it's often a good idea.

But it seems to me, that each entity can be broke apart to Model, View an Controller. I mean each entity has some data to store, some representation to view, and some actions to do. It would be nice to keep those parts of code separetly, so classes could be shorter and clearer to understand. I mean, yeah, MVC for tic-tac-toe is definetly overkill, but it's just to keep things as simple as possible. It would be nice to figure out how this design patter works on something simple.

I don't think it's true that each entity has all of those things. The player does not exist as a visible part of a game of tic-tac-toe, so why should there be a PlayerView? And if a Controller is strictly for collecting input, I don't see a need for a BoardController - input either goes to the Game or through the Players but the board itself is just where the state of the gameplay is stored.

The MVC pattern is not about splitting everything up into 3 parts, but to ensure that you're keeping your logic code separate from your presentation code, and both of those things separate from your input code. Some entities can be split up, but other entities only exist in one place or another.

Well, that's true, you're right.

Anyway, I would like to know how to put rest things together.

MVC was designed for user interfaces, so you should be careful in how you apply it. You certainly don't need a Model, View, and Controller class for each concept in your game.

For tic-tac-toe I would just have this:

Model classes: Game, Board, Player. Game owns board and players.

View classes: GameView, BoardView. Each view class references the relevant model class. GameView also owns BoardView.

Controller classes: GameController. This takes input and calls the relevant functions on the game. You don't really need controllers for each player or the board.

How do I connect them? Am I suppose to put Board and Players Models inside Game Model? If so, how do I attach Views to those Models? Do I need to store GameModel, GameView and GameController in some kind of container class Game? I read a lot about this pattern but can't find some concrete implementations in context of games.

I really liked this discussion here:

https://lukehalliwell.wordpress.com/2008/08/30/model-view-controller-is-extinct/

In a nutshell MVC is about separation of model and UI. I would not architect a game like this.

With games the salient point is that things that are meant to draw/represent really should not be making changes to the model. Any time you see someone referring to an entity as a sprite, or inheriting sprite for their entities there's going to be problems in the near future. Breaking yourself away mentally from the idea that the things on the screen are in any way real or substantial is the important part.

You're not "moving a character". You're drawing a sprite to the screen 60 times per second and selecting its image based on the state and logic of a set of numbers stored in microchips. An entity is not a sprite; and entity has a sprite. If you're only thinking of the entity as the thing it represents then you'll struggle with this. Once you start thinking of the entity as a class that holds together all of the relevant details and tasks associated with a specific unit of information then it becomes easier.

There is no game world, there is no player character, and there is no spoon. If you can really come to grips with that you'll automatically arrange your code to reflect it and you'll avoid a lot of awkward weirdness.

As for controllers, I honestly think it's best to have a layer of abstraction between the input and the recipient(s), but it's usually not that critical. Having the elements of the model being responsible for their own internal state is a matter of hygiene, but there's not really anything wrong with handing them a reference to an input controller or a snapshot of the input state or whatever you want to do. You don't need a barbed wire fence that separates things. You just want to understand the reasoning behind the principle and apply it where its appropriate.

It's worth mentioning that the move toward component-based design in the past several years has helped a lot with this.

void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

This topic is closed to new replies.

Advertisement