Reading.CleanArchitecture.Presenters

looks likt this is model view

(Clean Architecture by Robert C. Martin)

In this chapter, Robert C. Martin discusses the concept of humble objects and their role in isolating volatile or hard-to-test code. He introduces presenters as an example of humble objects used in the interface adapter layer to manage the separation of UI and business logic.


Key Concepts of Chapter 23

1. What Are Humble Objects?

  • Definition: A humble object is a design pattern where parts of a system that are difficult to test or prone to change are isolated into simpler objects.
  • The goal is to:
    • Make the volatile part of the code simpler.
    • Push complex, testable logic into other, more stable components.

Example:

  • The UI often contains both volatile code (e.g., rendering) and complex logic. A humble object separates these concerns, leaving rendering in the UI while delegating logic to a presenter.

2. The Role of Presenters

  • A presenter is a humble object that acts as an intermediary between the business logic and the UI.
  • Responsibilities:
    • Transform data from the use case layer into a format suitable for the UI.
    • Contain logic needed for presentation without embedding it in the UI code.
    • Avoid direct dependencies on UI frameworks, ensuring testability.

Example:

  • A presenter might convert a User entity into a UserViewModel for display in a web or mobile app.

3. Benefits of Using Presenters

  • Testability:
    • Presenters are easily testable since they do not depend on UI frameworks.
  • Decoupling:
    • Presenters separate the concerns of business logic and UI rendering.
  • Flexibility:
    • The same presenter can be reused across different UI implementations (e.g., web, mobile, or desktop).

4. UI and the Humble Object Pattern

  • The UI layer often has platform-specific code that is difficult to test.
  • By using humble objects (e.g., presenters), complex UI logic is moved to testable components, leaving only simple rendering in the UI.

Example:

  • A view in an Android app may rely on an MVP (Model-View-Presenter) pattern:
    • Model: Core business logic or use cases.
    • View: The actual Android UI elements (e.g., Activity or Fragment).
    • Presenter: Manages interaction between the model and view, handling logic like formatting data for display.

5. How to Implement a Presenter

Step 1: Define the Interface for the View

  • Create an interface for the UI (view) that the presenter will interact with
public interface UserView {
    void displayUserName(String name);
    void displayError(String message);
}

Step 2: Create the Presenter

  • The presenter interacts with the use case and formats the data for the view.
public class UserPresenter {
    private UserView view;
    private GetUserUseCase getUserUseCase;

    public UserPresenter(UserView view, GetUserUseCase getUserUseCase) {
        this.view = view;
        this.getUserUseCase = getUserUseCase;
    }

    public void fetchUser(int userId) {
        try {
            User user = getUserUseCase.execute(userId);
            view.displayUserName(user.getName());
        } catch (Exception e) {
            view.displayError("User not found");
        }
    }
}

Step 3: Implement the View

  • The view implements the interface and handles rendering.
public class UserActivity extends AppCompatActivity implements UserView {
    private UserPresenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        presenter = new UserPresenter(this, new GetUserUseCase());
        presenter.fetchUser(1);
    }

    @Override
    public void displayUserName(String name) {
        // Update UI with the user's name
    }

    @Override
    public void displayError(String message) {
        // Show error message in UI
    }
}

6. Testing the Presenter

  • Since the presenter depends on interfaces, it can be tested independently of the actual UI.
  • Example Test:
@Test
public void testFetchUser() {
    UserView mockView = Mockito.mock(UserView.class);
    GetUserUseCase mockUseCase = Mockito.mock(GetUserUseCase.class);
    UserPresenter presenter = new UserPresenter(mockView, mockUseCase);

    User mockUser = new User("John Doe");
    Mockito.when(mockUseCase.execute(1)).thenReturn(mockUser);

    presenter.fetchUser(1);

    Mockito.verify(mockView).displayUserName("John Doe");
}

7. Other Examples of Humble Objects

  • Database Gateways:
    • Abstract complex database logic into testable classes.
  • Controllers:
    • Extract business logic into use cases, leaving only simple coordination in the controller.

Key Takeaways

  1. Humble Objects Simplify Testing:
    • Isolate complex or volatile code into simpler, testable components.
  2. Presenters Decouple UI and Logic:
    • Presenters handle presentation logic, while views focus on rendering.
  3. Interfaces Enable Flexibility:
    • Use interfaces to abstract dependencies and promote testability.
  4. Reusability Across Platforms:
    • Presenters and other humble objects can be reused across different UI implementations.
This entry was posted in Без рубрики. Bookmark the permalink.