Sobes.tech
Middle

Can you explain the MVP (Model-View-Presenter) pattern in detail?

sobes.tech AI

Answer from AI

The application is divided into three main components:

  • Model: Represents data and business logic. It knows nothing about View or Presenter.
  • View: Responsible for displaying data and user interaction. Passive, contains no decision-making logic. Delegates all user actions to the Presenter.
  • Presenter: Acts as an intermediary between Model and View. Handles user actions, retrieves data from the Model, and updates the View. Contains presentation logic.

Pros:

  • Improved testability (Presenter logic is easily tested in isolation).
  • Separation of concerns.
  • Reuse of presentation logic (in different Views).

Cons:

  • Increased number of classes.
  • Boilerplate code (View and Presenter interfaces).

Interaction:

  1. View notifies the Presenter about user actions.
  2. Presenter interacts with the Model (fetches/saves data, performs business logic).
  3. Presenter receives results from the Model.
  4. Presenter updates the View by calling its methods.

Example:

// View interface
interface MainView {
    void showProgress();
    void hideProgress();
    void displayData(String data);
    void showError(String message);
}

// Presenter interface
interface MainPresenter {
    void attachView(MainView view);
    void detachView();
    void fetchData();
}

// View implementation (Activity/Fragment)
public class MainActivity extends AppCompatActivity implements MainView {
    private MainPresenter presenter;
    // ... implementation of interface methods
}

// Presenter implementation
public class MainPresenterImpl implements MainPresenter {
    private MainView view;
    private Model model; // Reference to Model

    @Override
    public void attachView(MainView view) {
        this.view = view;
        this.model = new ModelImpl(); // Initialize Model
    }

    @Override
    public void detachView() {
        this.view = null;
        this.model = null;
    }

    @Override
    public void fetchData() {
        if (view != null) {
            view.showProgress();
            // Request data from Model
            model.getData(new Model.DataCallback() {
                @Override
                public void onSuccess(String data) {
                    if (view != null) {
                        view.hideProgress();
                        view.displayData(data);
                    }
                }

                @Override
                public void onError(String message) {
                    if (view != null) {
                        view.hideProgress();
                        view.showError(message);
                    }
                }
            });
        }
    }
}

// Simple Model
interface Model {
    interface DataCallback {
        void onSuccess(String data);
        void onError(String message);
    }
    void getData(DataCallback callback);
}

class ModelImpl implements Model {
    @Override
    public void getData(DataCallback callback) {
        // Simulate data retrieval
        new Handler().postDelayed(() -> {
            callback.onSuccess("Data from Model");
        }, 1000);
    }
}