6

In my board game I want to decouple my Player and Board class since I've changed piece moving system several times now and it's been a chore each time. I think I could use some interface for taking a player request to alter the board state but I can't decide if a Command or a Mediator interface is the appropriate solution (or even Observer?)

My understanding is that a Command executes something a that a client wishes to do to a receiver while not knowing how they do it. But does a Mediator not do mostly the same thing? You specify a request object and the mediator executes the requests on client behalf? Does the Mediator facilitate two-way communication e.g. can a player request to move a piece and if successful, can the board in turn notify the player of the new board state?

Basically, I'm having trouble knowing which way to decouple my classes between 3 seemingly related patterns. I've read the GoF discussion on this and I'm still confused since they don't use concrete examples of when they'd be more useful than one another.

  • A command captures the idea of a single operation to be performed along with the state (arguments, i.e.), required to do it. So it's an object on its own abstracting the idea of something to do. Mediators abstract the communication that goes on from one thing to another, and they don't necessarily just perform one operation, and they don't necessarily persistently store the information required to perform those operations. For your case the command pattern would likely be a closer fit to represent the moves that could be applied. – user204677 Jan 17 '18 at 16:25
  • If you use the command pattern, it might store like all the data required needed to perform a "move" command which it can execute at any given time. Sometimes people provide undo methods and state as well to the command interface so that the opposite action can be performed. – user204677 Jan 17 '18 at 16:28
  • @TeamUpvote thanks for the clarification, I think the undo potential in a MoveCommand is going to be useful for me. Follow up question: Could a command object reference strategy objects? Like if a player moves a certain piece, the specific move behavior is dependent on the type of piece being moved, each move type being encapsualted in a strategy object – swigganicks Jan 17 '18 at 17:00
  • Don't see why not -- the strategy would be kind of an implementation detail for the command execution in that case to let you more easily choose and swap out algorithms. That said, I'm not the biggest fan of design patterns. :-D I tend to not think about them upfront so much as use them to communicate the characteristics of my design decisions later in hindsight to other people. I find them useful for communication in hindsight but not so much about thinking how to design things in foresight. – user204677 Jan 17 '18 at 17:20
  • 1
    @TeamUpvote I hear you about design patterns, I traditionally haven't used them upfront in my designing but I'm getting tired of making something that works perfectly fine until I need to add a new feature. I feel like I might be over-engineering this but I really don't want to waste time refactoring when implementing planned new features in the future – swigganicks Jan 17 '18 at 17:56
4

Is it the right question ?

The Mediator is about the interactions between "colleague" objects who don't know each other. The Command is about how to execute one specific interaction (whether the command is created by a Player or by a mediator). The question should therefore not about which alternative to use, but how each of them could serve your purpose.

How could the Mediator help ?

The purpose of the mediator pattern is to encapsulate the interaction between several colleague objects in order to isolate them from each other. Using the mediator to decouple a Player and a Board would make the design a little complex:

  • Player and Board would implement the same common Colleague interface
  • Player sends move requests to Mediator
  • Mediator knows that player requests are to be sent to Board
  • Board receives request from Mediator
  • Board analyses request and informs Mediator that it was accepted (or rejected)
  • Mediator knows that these kind of interaction are to be sent to Player
  • Player receives answer from Mediator

Furthermore, as stated in GoF, it could be useful to make Mediator an observer to the different colleagues, so that it is informed of relevant state changes and can trigger actions.

The advantage of this more complex approach is its flexibility: you could have 2 Players and a Board for example. You could add a timer Colleague. You could add an adviser/coach Colleague to inform the human player of how good his move is (or provide similar information to a machine learning AI player).

Furthermore, as the colleagues are decoupled, you could potentially reuse them in other games.

What about the Command ?

The purpose of the command pattern is to encapsulate requests. So you'd encapsulate the moves for the board and let them be executed (or reversed in case the user activates an undo).

You'd certainly use an observer pattern, to let the Player observe the Board state change. And may be a second Player (AI or human) would also subscribe to the Board change and issue commands to trigger moves. And you'd certainly have a main loop for the game, in which you could add a timer.

In the end, you would have a similar structure (game loop glues together the pieces). However, the objects need to know each other, and a change in the interaction between the objects might require adaptations of all the involved classes.

Recommendations

  • If you want to allow an undo, you'd better use the Command.
  • If you have only two colleagues, the mediator seems a little over-engineered if you only have a single game. It further may constraint the rest of the design. So maybe start without it and refactor the code when you have something working.
  • If you're interested in game coding in general, Mike McShaffry's book "Game Coding Complete" is for you : he explains how to structure a game, the challenges, and the pitfalls to avoid. There's not much theory about patterns, but a lot of common sense about working game architectures.
  • 1
    Very good answer. Small note: it is not necessary that all colleagues implement a common Colleague interface. In the GoF book this is just coincidental since they're talking about a GUI widget hierarchy. There is no dependency on this interface. It's just important that each colleague holds a reference to the mediator in order to initiate events. Here, the Board and Player would generate completely different kinds of events and should not share an interface. – amon Jan 18 '18 at 13:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.