Question

In Robotlegs does the domain logic needs to be in the Commands(controller) or the Models?

Example: lets say i'm building a "Tic Tac Toe" game. i have: GameMadiatore,CellSelectedCommand,BoardModel.

After the user clicks on a cell the "GameMadiatore" fires an event that initiates "CellSelectedCommand". Does the "find 3 in row" win logic needs to be in the "BoardModel" or "CellSelectedCommand" or some other command?

Was it helpful?

Solution

I would advise you to create atomic commands.

This means a command should do 1 thing and 1 thing only. This allows you to easily rewire your application logic without refactoring too much later on.

In the case described above your thinking is correct another command will do just fine. For example:

  • CellSelectedCommand
  • Check3InRowCommand
  • StartNewGameCommand
  • PlayerWinsCommand
  • ..

Some more principles about MVCS:

  • Mediator: Should be considered as a mail man. It will act as a go-between between your views and your application. Call it a ViewController if you will, but then a bit more rudimentary.
  • Command: Can be considered as the controller logic, all the decision making can be done here. Update your models from here.
  • Model: Should only reflect application state. For example a boolean that indicates whether the game has been won.

Cheers

OTHER TIPS

As @DennisJaamann said - a Command should only do one thing. It should, however, not ever contain the actual domain logic. Neither should it be in the Model, nor in the View classes.

Here's why: If you put your game logic into framework specific classes, you will forever tie your game to this one specific framework (even if it's admittedly a good one). The game rules of TicTacToe, however, should always remain the same, regardless whether they're used with RobotLegs, PureMVC, or whatever other choice of technology you make. If, for example, in a few months, you decided to create a version of the game for some fancy new mobile device, and you want to use vendor specific MVC framework and components, you would otherwise have to do everything again from scratch. Plus, spreading the game logic over several command classes makes it much harder to follow, read and understand the code - this makes debugging a real pain.

As Uncle Bob Martin would put it: The framework is a delivery mechanism. No more, no less. It should be used to deliver the information, i.e. present it to the user, and process user interaction events. But the actual domain logic should be in framework agnostic use case classes that have inverted dependencies, and are thus completely decoupled from the delivery mechanism.

So, I would create a game interface, maybe just call it ITicTacToe, and implement it in a game class, TicTacToe, which contains both the state (i.e. which cells have already been marked) and logic (i.e. check if there's three in a row) to perform and monitor a single round of TicTacToe. These things belong together, because they are used for the same purpose, and they have the same single reason to change: If, and only if, the rules of TicTacToe change!

Use TDD to implement the game's behavior, and have the game class dispatch events whenever the game is won or lost, instead of keeping track of scores etc. - these are part of the application logic around the game, but not of the game itself.

You can then inject the game into your CellSelectedCommand, have that command call the appropriate methods on the game class, listen to the local game events, if any, and then dispatch application-wide ones via the central dispatcher. You can then use these to trigger separate GameWonCommand and GameLostCommand classes to add points to the score and retain it in the ScoreModel. Models should only contain shared state, i.e. data that is needed by more than a single task. I like to think of models like drawers and boxes on a big shelf: You take out some data you need to perform a task (i.e., some user info prior to starting a game), process it (play), then store it away afterwards (save the score).

To sum it up, here's a rule of thumb: Always try to keep your core application logic agnostic to frameworks and delivery mechanisms - they should be extensions, plugins, if you will, rather than the center of the system.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top