» Refactor to MVC

Refactor to MVC

Hi! It’s been a while since my last post. My live has changed so much! I finally left my dryasdust work at a large IT consulting company, and got another job at a small Dutch company. Dutch people rock! I changed my job, I changed my house, I lived all new kind of experiences in different countries… And I also changed my mind! Now let’s code again!

Today I’m going to explain how I managed to refactor the old structure to fit MVC pattern. To make it short, I’ll explain what MVC is, and then make a practical exercise to understand the implementation.

You won’t need to download the game code to be able to follow this post, but, if you feel curious, here’s the direct link to the GitHub repository. You can also find the last compiling build in the Download page.

Summary


1. MVWhat?

M: Model.

V: View.

C: Controller.

This pattern helps us to encapsulate responsibilities. As you start programming a videogame, or any other program that has a UI, you will probably glimpse a grouping of functionalities: The stuff in charge of the interaction with the user, the stuff in charge of data, and the stuff in charge of internal calculations. MVC architecture allows you to cleanly split these groups of functionalities.

There exist lots of books that describe MVC, but if I could recommend one, I’d choose “Head First Design Patterns”. This book is very funny and easy to understand. Let me use its diagram to explain what MVC is:

mvc_diagram

 

Here! I told you it was a good source. As you can see in the diagram above:

  • The View is the UI. As the user sends an input, the View will notify the Controller that something happened.
  • The Controller will take that notification and will notify the change to the Model.
  • The Model will change its data depending on the parameters received, and then it will notify everyone that he has changed.

Well, this is quite a sober explanation; I don’t want to get you confused. Keep those three concepts in mind and start reading the implementation, where it will probably become clear to you.


2. Implementation

2. 1. Extracting Model and View

There’s something in the refactor process that we call “smells”. Martin Fowler describes code smells like this in his book “Refactoring – Improving the Design of Existing Code“:

Certain structures in the code that suggest (sometimes they scream for) the possibility of refactoring.

You can find a catalog of code smells here.

Now take a look at this class. Look at the comments, yet in the first lines of code:

Doesn’t it smell a bit? What those comments are doing, is to separate the UI variables from the Data variables. “nekomata” is an Actor, and “dynamicBody” is the Body. In other worlds, nekomata is the picture of the kitten that is shown to the user, and dynamicBody is the calculated data that is processed internally.

This is a clear example of Data Clump, wich must be fixed using Extract Class, which means, to create classes that enacpsulate those variables and methods that can be decoupled.

Let’s do it little by little.

First, we will create three new classes:

-       KittenView

-       KittenModel

-       KittenController

The last one may not have much sense now, but don’t worry for now.

Next step consists in identifying which part belongs to which class. You can try yourself, or you can take a look at this code, where I’ve added some comments to make it easier. A technique that works for me is to move the variables already identified, and then look at the compiling errors. They will give you a hint about which components must be moved.

You must also mind the class implementations and extensions. In this case, the class “Actor” corresponds to the view and “ICollisionable” must be implemented by the model, this way:

Now start moving each element from Kitten to KittenModel and KittenView. It is important to know that the Model is a standalone class, it should be decoupled from the other elements of MVC. So it is a good idea to start the refactor with this class.

Here’s the result:

KittenModel

KittenView

Notice that KittenModel only contains its own elements, while KittenView needs model’s information. For example, in the method “UpdateAnimation”. As explained before, the View changes the animation depending on the Model’s data. It needs to know the velocity and angle of the physics simulation to show a concrete animation:


2.2. Implement the MVC pattern

Now that we’ve assigned the responsibilities, it will be easier to implement the MVC pattern. I will try to explain how I did it, but if you don’t like my style you can find other implementations over the net.

This is how my structure looks like:

IMG_2721

The Model is observed by the View. To make it observable, I used PropertyChangeSupport and created this class, meant to be extended by Models:

Then use “notifyUpdate” when the data changes. For example, when the position changes:

Next, we must prepare de View to get those notifications. To get this done, make the View implement PropertyChangeListener, and override the propertyChange method to manage the notifications received:

Good! Now the only thing that left to do is create the Controller to put all together. You will find the complete implementation on a link later but, for now, to focus on what the controller actually does, read the code below:

When the game asks the KittenController to create a new Kitten for him, the KittenController will create both the KittenView and the KittenModel, subscribe the View to the Model’s notifications and, finally, add the Kitten to the World:

There we are! Almost done. Just let me explain briefly how the user’s input will finally modify the Model.

In the game, when the user clicks on the picture of a kitten, drags, and then releases the cursor, the kitten will start moving to the point where the cursor lifted (the Waypoint). But actually, the view does NOT move anywhere by itself. What really happens is that the user sends an order to the View. The View notifies the controller that the user dragged the cursor. The Controller asks the model to react to a cursor drag. The model makes the physical object move to the Waypoint, and this action fires a PropertyChanged event that will be cathed by the View.

This way:

IMG_2722

Code:

And this is how all works together. I think I’m not forgetting anything, and that the explanations where understandable… I’m leaving the final implementation below, that way you will have an overview:

KittenModel

KittenView

KittenController


 Conclusion

This was quite didactical :) I like how the post looks like. I’m not sure what to do next. I’m curious about the skeletal animation. I’ve been nosing around Spine… Or maybe I should start making something more concrete, like a first level? I’ll think about it.

Thanks for reading! Don’t forget to share and comment! See you soon ^^

#FightingKittenBlog

Leave a Reply