• 4 hours
  • Easy

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 2/18/22

Implement the Controller and View for Your Application

Our next step in building an MVC app is planning out what goes in our controller. Let's dive in!

How Do You Plan Out the Controller?

The controller is responsible for the sequencing of user interactions. Looking at the game play, the sequence looks like:

  • Create the deck.

  • Enter player names.

  • Shuffle the cards.

  • Deal a card to each player.

  • Flip over the cards.

  • Evaluate the winner.

  • Display the winner.

  • Reconstitute the deck.

The controller then needs to know which step you are on, and a valid input for that step.

How does the controller know what’s been inputted?

The input command comes from the view. The controller evaluates that input. Any invalid input is then either ignored or throw an error exception. (You decide the infraction severity, and how to inform the user of the invalid input via the view.)

What we need to do now is look at the sequence of steps above and find the interactions between the controller and the view:

Start the Game

The first step of any interaction is to instantiate the controller. The controller builds the core game objects. These are the deck, and an empty list of players. It also needs to know about the view. The view should be created elsewhere, and passed to the controller, rather than having the controller make its own.

Why do we need to have the view passed to the controller, instead of just making it? 

Well, if you were to create a mobile version of this application, it would need different UI (view) elements. You'd then have to modify the controller to make them. It would violate the SOLID principles via the open/closed principle.

Entering Player Names

After every name, the controller adds the name to the list of players.

Indicating Name Entry is Complete

The controller tells the view to draw the game state, which refers to the current set of values from various objects. At this point, it only consists of one player.

Deal Cards

The controller shuffles the deck and then removes the top card and put it into a player’s hand. The controller then tells the view to draw the game state. It now consists of player names and a face-down card for each player.

Flip Over/Reveal Cards

The controller flips over each player’s card and then evaluates the winner. The controller tells the view to draw the game state, which now includes the name of the winning player. The cards are taken back from the player and put back into the deck.

Play Again

The controller returns to Step 3.

How Do You Implement the Controller?

The controller should have methods for each of the user interaction steps. The view calls these methods. After each step, the controller informs the view about the new game state.

Let's create these methods together!

public class GameController {
	public GameController(View view, Deck deck) {}

	public void addPlayer(String playerName) {}
	public void startGame() {}
	public void flipCards() {}

	void evaluateWinner() {}
	void displayWinner() {}
	void rebuildDeck() {}
};

Let's look at what we've built.

  1. Start the game corresponds to the view, deck, and GameController being created elsewhere (in main.java). The GameController is passed in the view and deck.

  2. Entering player names corresponds to the  addPlayer  method.

  3. Indicating name entry is complete is handled by the  startGame  method. (Once a game is started, we don't allow adding of players).

  4. Deal cards is also handled by the  startGame  method, as it's the first thing that happens at the beginning of the game.

  5. Flip over/reveal cards is handled by the  flipCards  method. This is also where the winner is determined, and the view is called with the name of the winning player.

  6. Play again recovers all the dealt cards, and puts them back in the deck, then takes the game state back to Step 3.

How Do You Plan Out the View? 

Remember that the view is both the user interface and the event generator. The controller calls the display methods of the view exclusively. Therefore you should look at what the controller is telling the view to show. But you don’t want the view accessing model information directly (this would violate single responsibility). So instead of passing in a player, you should only pass in a player’s name. It’s the minimum amount of data necessary to indicate that model (player) information at this time. The same thing goes for the playing card. You can pass it the rank and suit to display, rather than the entire PlayingCard.

Let's do this together!

public class View {
    public void showPlayerName(int playerIndex, String name);
    public void showFaceDownCardForPlayer(int playerIndex, String name);
    public void showCardForPlayer(int playerIndex, String Name, String rank, String suit);
	public void showWinner (String winnerName);
};

Looking at what we've added:

  1. Entering player names: the view sends the entered string to the controller, which calls back the view's showPlayerName method.

  2. Deal cards: calls the view's showFaceDownCardForPlayer method.

  3. Flip over/reveal cards: calls the view's showCardForPlayer and showWinner methods.

Looking at the entire set of interactions, MVC recommends that the UI gather the input, and then forward it to the controller, which in turn calls back the view.

View (calls) -> controller (calls) -> View
View (calls) -> controller (calls) -> View

For example, after a name is entered, it would call the  controller.addPlayer(playerNameString)  method. The controller calls back the view with a new  showPlayerName(playerIndex, name)  call.

This seems like overkill. Why can't the view just hold onto the player names?

I can give you a SOLID reason. 😉 The model objects are responsible for maintaining the state information. Player objects already know the name they are storing (their single responsibility), so might as well keep that data in only one place.

How Do You Implement the View? 

Our implementation is straightforward. It just shows the player names, the cards dealt and results on the command line. But, since we've separated this functionality, we could easily replace the mechanism with a GUI implementation.

Let's do it together.

// simple, command line implementation
// View does not need to keep a list of players
// this will be called by GameController every time it wants to show a player name
public void showPlayerName(int playerIndex, String name) {
    System.out.println("[" + playerIndex + "][" + name + "]");
}

Looking at what we added, we now have a simple user interface, that displays the information told to us by the controller.

But we must go back to the controller and call these methods where needed. And we need to tie everything together in a game class that has the main function.

Let's Recap! 

  • The controller is responsible for sequencing a use case and validates events sent by the view.

  • The view is responsible for presenting the model and sequence information and gathering input from the user.

  • The controller's responsibilities are determined by looking at the steps of the application. The view's responsibilities are determined by what the controller needs to show to the user.

We now have a functioning application that followed the MVC approach. In the next part, we begin applying the SOLID design principles one by one, to strengthen our application.

Example of certificate of achievement
Example of certificate of achievement