Problem?
I have been looking at MVP implementation and process to design a good domain model (not anemic). It says that the domain model should have its own behavior and not being a simple data model (like DTO).
In my case (my application), it turns out that controllers architecture is following the model architecture (player model, player controller, game model, game controller, ...). So I think my model is anemic because my model objects does not contains references to other models objets, they define a lot of accessors methods (get & set) and finally their core methods only modify their own object properties.
How do I integrate a Model handling business logic into MVP architecture? And who should manage which kind of action? Does the presenter architecture have to follow the model architecture? Should a presenter only have access to a part of the model or all of them? Does the presenter have to listen to model modification and react accordingly? Any concret resource on the net with examples?
Solution?
Create a structured Model with inheritance and behavior. Link related model objects (like collections, property of another model object, ...). Finally listen to model events modification into controllers for sending requests onto network.
But, in that case, the role of the controller is very small, because the model handle almost every modification itself. Isn't it better to "flatten" the model hierarchy, so they are not dependency between each others ?
I am confused.
Here is an example of my current app architecture
In the following cases, I think the model is anemic.
Context: In multiplayer game application over network. Let's say we have two players with a certain amount of balls that they have to throw into a barrel (players have their own barrel each). Its a turn based game.
So the domain model would be (properties are not typed):
- Game (playerTurn)
- Player (name, score, number of balls thrown)
- Ball (color, weight)
- Barrel (distance, points, list of balls thrown into)
In the MVP representation, I would create three Presenters:
- GameController
- PlayerController
- BarrelController
Example of use
Use case n°1: The player (real one) throws a ball
In resume, player throws a ball. Event is dispatched to GameController which validate action over network and responds back by delegating event to each specific controller.
code for generating (and modify) diagramm ()
View -> PlayerController : onThrowBall()
PlayerController -> GameController : onPlayerThrowsBall()
GameController -> GameModel : isTurn()
GameModel --> GameController : true
GameController -> Network : onPlayerThrowsBall()
Network --> GameController : true
GameController -> GameModel : updateTurn(player)
GameController -> PlayerController : throwBall()
PlayerController -> PlayerModel : updateBallThrownCount()
PlayerController -> View : update()
Use case n°2: The thrown ball fall into the barrel
Same principe, action is dispatched for validation (and perform potential related action into parent controllers). Finally, barrel is updated by BarrelController (add ball) and player model is updated by PlayerController (update score).
code for generating (and modify) diagramm ()
View -> BarrelController : onBallFallIntoBarrel()
BarrelController -> PlayerController : onBallFallIntoBarrel()
PlayerController -> GameController : onBallFallIntoBarrel()
GameController -> GameModel : isTurn()
GameModel --> GameController : true
GameController -> Network : onPlayerThrowsBallIntoBarrel()
Network --> GameController : true
GameController -> GameModel : updateTurn()
GameController -> PlayerController : throwBallIntoBarrel()
PlayerController -> BarrelController : throwBallIntoBarrel()
BarrelController -> BarrelModel : addBall()
PlayerController -> PlayerModel : updateScore()
PlayerController -> View : update()