MVP 패턴에서 View는 UI 내용을 기반으로 Model 객체를 인스턴스화해야합니까, 아니면 이러한 내용을 매개 변수로 Presenter에 전달해야합니까?


9

개발중인 Android 앱에서 MVP 패턴을 사용하고 있습니다.

기본적으로 4 가지 요소가 있습니다.

  1. 새 사용자를 추가 할 수있는 AddUserView :
  2. AddUserPresenter
  3. UserInfo (포조)
  4. UserInfoManager (비즈니스 로직 및 스토리지 관리자)

내 질문은 :

AddUserView에서 "Add"버튼을 누르면 텍스트 뷰의 내용을 가져 와서 새로운 UserInfo를 인스턴스화하여 Presenter에 전달해야합니다. 또는 AddUserView가 textViews 내용을 가져 와서 AddUserPresenter로 전달해야합니까? 이는 실제로 UserInfo를 인스턴스화하여 UserInfoManager로 전달합니까?

답변:


8

Martin Fowler의 MVP 설명에 따르면 ( http://martinfowler.com/eaaDev/uiArchs.html )

파울러는 MVC의 View 부분에서 다음과 같이 말합니다.

Potel의 첫 번째 요소는보기를 위젯 구조, 양식 및 제어 모델의 제어에 해당하는 위젯의 구조로 취급하고보기 / 컨트롤러 분리를 제거하는 것입니다. MVP보기는 이러한 위젯의 구조입니다. 위젯이 사용자 상호 작용에 반응하는 방식을 설명하는 동작이 포함되어 있지 않습니다 .

(굵게 강조된 광산)

그런 다음 발표자 :

사용자에 대한 적극적인 반응은 별도의 발표자 객체에 존재합니다. 사용자 제스처에 대한 기본 핸들러는 여전히 위젯에 존재하지만 이러한 핸들러는 제어를 발표자에게 전달 합니다.

그런 다음 발표자는 이벤트에 반응하는 방법을 결정합니다. Potel은이 상호 작용에 대해 주로 명령 및 선택 시스템에 의해 수행되는 모델의 동작 측면에서 설명합니다. 여기서 강조 할 유용한 점은 모든 편집 내용을 명령으로 모델에 패키징하는 방법입니다. 이는 실행 취소 / 다시 실행 동작을 제공하기위한 좋은 기반을 제공합니다.

(또, 대담한 강조 광산)

따라서 Fowler의 지침에 따라 귀하의 View는 버튼 이벤트에 대한 반응에 대해 책임을지지 않습니다. 의 인스턴스 생성이 포함됩니다 UserInfo. 객체 생성을 결정하는 책임은 UI 이벤트가 전달되는 Presenter 메서드에 속합니다.

그러나 textViewView는 버튼 이벤트를 발표자에게 전달 하기 만하면되기 때문에 View의 버튼 이벤트 핸들러도 사용자의 내용을 전달할 책임이 없다고 주장 할 수 있습니다 .

MVP를 사용하면보기에서 발표자가보기 자체에 여전히 무관심을 유지하면서 발표자가보기에서 직접 데이터를 선택하는 데 사용할 수있는 인터페이스를 구현하는 것이 일반적입니다. UserInfo는 간단한 POJO이므로 ,보기가 인터페이스를 통해 View에서 fron을 선택할 수있는 UserInfo 의 getter 를 노출하는 것이보기에 유효 할 수 있습니다 .

// The view would implement IView
public interface IView {

    public UserInfo GetUserInfo();
}

// Presenter
public class AddUserPresenter {

    private IView addUserView;

    public void SetView(IView view) {
        addUserView = view
    }

    public void onSomethingClicked() {

        UserInfo userInfo = addUserView.GetUserInfo();
        // etc.
    }
}

UserInfo이벤트 핸들러를 사용하여 뷰에 직접 전달하는 것과 다른 점은 무엇입니까? 가장 큰 차이점은 발표자가 여전히 개체를 만드는 논리에 대한 책임 UserInfo이 있다는 것입니다. 즉, 이벤트는의 생성 전에 발표자에게 도달하여 발표자 UserInfo가 결정을 내릴 수 있도록합니다.

UserInfo보기 내의 특정 상태를 기반으로 작성하기를 원하지 않는 발표자 로직이있는 시나리오를 상상해보십시오 . 예를 들어, 사용자는 뷰에 체크 박스를 쳤다하지 않은 경우, 또는 당신은 실패한 사용자 정보에 추가 할 몇 가지 필드에 대한 유효성 검사를했다 - 발표자가 호출하기 전에 추가 검사를 포함 할 수 있습니다 GetUserInfo- 즉,

    private boolean IsUsernameValid() {
        String username = addUserView.GetUsername();
        return (username != null && !username.isEmpty());
    }

    public void onSomethingClicked() {            

        if (IsUsernameValid()) {
            UserInfo userInfo = addUserView.GetUserInfo();
            // etc.
        }
    }

이 논리는 발표자 내부에 남아 있으므로 뷰에 추가 할 필요가 없습니다. 뷰가 호출에 대한 책임이있는 경우, 뷰를 사용하는 GetUserInfo()모든 로직에 대한 책임도 있습니다. 이것이 MVP 패턴이 피하려고하는 것입니다.

따라서 UserInfoView 클래스에 실제로 존재 하는 메서드를 생성하는 동안 Viewer 클래스에서는 호출자가 아니며 Presenter에서만 호출되지 않습니다.

물론, UserInfo사용자 입력 위젯 (예 : 문자열 변환, 유효성 검사 등)의 내용에 대해 추가 검사가 필요한 경우 유효성 검사 / 문자열 변환을 수행 할 수 있도록 개별 게터를 노출하는 것이 좋습니다. 발표자 내에 배치하면 발표자가 사용자를 만듭니다 UserInfo.

전반적으로, 발표자 / 전망 사이의 분리에 관해서 당신의 주요 목표는 보장되어 결코 보기에 쓰기 로직을 필요가 없습니다. 위젯 속성의 상태에 관한 명령문 인 if경우에도 ( if빈 텍스트 상자 또는 체크 박스의 부울 확인) 어떤 이유로 든 명령문 을 추가해야하는 경우 발표자에 속합니다.


1
좋은 답변 @ BenCottrell! 그러나 나는 또 다른 하나를 가지고 있습니다 :) onSomethingClicked()사용자가 "뭔가"를 클릭하면 View 호출 방식으로 발표자 메서드의 이름을 지정하는 것이 좋습니다 presenter.onSomethingClicked(). 또는 내 발표자 방법을 의도 한 작업으로 지정해야 addUser()합니까?
Rômulo.Edu

1
@regmoraes 좋은 질문입니다. 내 예제 코드에서 약간의 냄새 가 강조되었다고 생각합니다 . 는 PresenterUI 로직보다는 도메인 로직 코스의 책임이며, 구체적으로 맞춤 View이라는 방법이 존재해야하므로 개념, UI 개념이다 따라서, onSomethingClicked()실제로 적합하다. 가늠자로, 위의 예제에서 선택한 이름은 냄새가 좋지 않습니다 :-).
Ben Cottrell

@ BenCottrell 첫째로 많은 답변을 주셔서 감사합니다. 나는이 가진 유효한의 이해 GetUserInfo당신이 언급 한 바와 같이 가능한 대해 (발표자에서 트리거됩니다)보기에 어떤 방법을 if내부 조건 GetUserInfo방법은? 어쩌면 UserInfo의 일부 필드는 사용자 반응을 통해 설정됩니까? 시나리오 : 아마도 사용자가 확인란을 선택한 다음 일부 새로운 구성 요소 (새로운 EditText)가 사용자에게 표시됩니다. 이 경우 GetUserInfo메소드는 if 조건을 갖습니다. 이 시나리오에서는 GetUserInfo여전히 유효합니까?
blackkara

1
치료 고려 @Blackkara UserInfoA와 모델 - 중 -보기 내가 추가 할 것이라고 시나리오 - (일명 "보기 모델") boolean체크 상자와 빈 / 널 (NULL)의 상태 String로 텍스트 상자의 상태를 UserInfo. UserInfoViewModelPOJO가 UserInfoPresenterView 상태에 대한 정보를 찾 도록하는 것이 진정한 목적인 클래스라는 점에서 생각하는 데 도움이된다면 이름을 바꾸는 것도 고려해 볼 수 있습니다 .
벤 Cottrell
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.