How do I create a flexible MVC structure?

194 Views Asked by At

As part of the training scheme I am on at the moment, I have been tasked with developing a simple command-line based helpdesk application. The point of the project is to develop our abilities to use design patterns, SOLID principles, MVC architecture etc.

I am having problems with understanding how to keep my MVC structure flexible. Here is a sample of one part of my code...

public class RegisterController 
{   
    View view;
    RegisterModel registerModel;

    public RegisterController()
    {
        registerModel = new RegisterModel();
    }

    public void processRegistration(String username, String password, Role role)
    {
        if(registerModel.isRegisterable(username, password))
        {
            User newUser = new User(username, password, role);
            registerModel.registerUser(newUser);
            view = new LoginView(new LoginController());
        }
        else
        {
            System.out.println("ERROR during registration.");
            view = new MainView(new MainController());
        }

        view.startView();
    }
}

I ideally want to be able to go in at a later date and substitute it with a different user interface (view classes) e.g. a web page, without altering my model or controller. However, at the moment you can see that I am coding to a concrete implementation of my command line "MainView" and "LoginView" classes.

How can I make this controller code more flexible and allow substitution with a different user interface with minimal code modification? Is it unrealistic to expect the controller code to remain the same when changing to a different UI?

1

There are 1 best solutions below

0
On

One of the major benefits of the MVC/MVP design patterns is that they allow you to unit test your presenters, while mocking the view and model.

As a result, I would always recommend the controller/presenter is constructed with the view and model passed as arguments to the constructor. If the view and model are passed as interface types, then they can be substituted in a test scenario with mocked objects. In your current design, the concrete implementation is chosen within the controller, which breaks this paradigm.

I typically link my controllers and views in one central location. However, this assumes the controllers are not going to immediate launch expensive computation actions upon construction. I'm not sure there is a perfect answer to this, but I'm confident you should adjust your current design to allow for testing.