-
-
Notifications
You must be signed in to change notification settings - Fork 6
Dev Architecture
LSML uses a slightly unorthodox variation of the MVC pattern.
The pattern consists of:
- View
- Model
- Command
- Message
This is how the different concepts interact:
The view issues commands in response to user interaction. These commands manipulates the model(s) and sends messages depending on their function. The view can then listen to these messages and update its presentation by reading the model in response to the message.
The idea behind this pattern is that the Model is free from the responsibility of generating notifications or messages that the view can listen to. This simplifies the model and makes the model easier to test; the correctness of the model is very important and hence the ease of testing is a high priority.
The Commands become quite small as they only manipulate the public interface of the Model and send on messages. Because of this, the message passing interface and the model can be mocked to completely test the command in isolation. A universal mock model can be constructed (MockLoadoutContainer) to make command testing even easier.
Messages have very little code and are not deemed worthy of testing as the chance for errors in messages is negligible. Even so the tests of Commands usually exercise the Message code too.
Another benefit from this pattern is that if the model would send notifications on change, a large composite operation would generate many (possibly redundant) notifications which would cause many UI updates. But with the Command generating the messages, the Command can decide when and what messages to generate to reduce UI updates.
Finally, as the Command, Message and Model never rely on the View, the View is completely exchangeable without modifying either the Commands, Model nor Messages.
The model code can be found in the model
package and the commands can be found in the command
package. The view classes are of course found in the view
package. The messages are interspersed inside of the model
package for the moment.
Message passing is done through two interfaces: MessageDelivery
and MessageReception
.
MessageDelivery
is an interface that you can deliver messages to, typically passed as an argument to a Command that needs to send messages.
MessageReception
is an interface which you can register with to have messages delivered to you.
MessageRecipient
is an interface which you have to implement to be able to register for messages with a MessageReception
object.
The class MessageXBar
implements a 1-to-n message broadcast channel. It implements both the MessageReception
and MessageDelivery
interfaces; i.e. you can register with it to have messages delivered to you and you can post messages to it to have it delivered to anyone who is willing to listen.