2023-07-19

Guice and MVP pattern: decouple the view from the presenter

I'm writing an application in Swing and I'd like to make use of Model–view–presenter pattern. I found a sample application using this pattern and alter it to use Guice. I was able to make it work with albeit with one problematic piece of code. Let me first show my code and later on the piece I find problematic.

Application starting point:

@RequiredArgsConstructor(onConstructor = @__(@Inject))
public class Main {

    private final View view;

    public static void main(final String[] args) {

        final Main main = Guice.createInjector().getInstance(Main.class);

        SwingUtilities.invokeLater(main.view::createUI);
    }
}

Model:

public class Model {

    public String getPassword() {
        return "password";
    }
}

Presenter:

@RequiredArgsConstructor(onConstructor = @__(@Inject))
public class Presenter {

    private final View view;
    private final Model model;

    public void login(final String password) {

        final String result = model.getPassword().equals(password)
                ? "Correct password" : "Incorrect password";

        view.updateStatusLabel(result);
    }
}

Until this point everything seems to be fine. In the View constructor I manually create instance of Presenter using this (due to some coupling involved in MVP pattern) instead of letting Guice does it job.

EDIT

How do I overcome this problem? As per comments, I'd like to rewrite the code so that the view could be injected into the presenter via dependency injection.

Guice has this somewhat covered it its documentation, however, I find it really difficult to understand hence this question of mine.

public class View {

    private final Presenter presenter;

    private JLabel statusLabel;
    private JTextField inputField;

    public View() {
        // manually adding this, should be DI
        this.presenter = new Presenter(this, new Model());
    }


    public void createUI() {
        // removed
    }

    //called by the presenter to update the status label
    public void updateStatusLabel(final String text) {
        statusLabel.setText(text);
    }
}


No comments:

Post a Comment