Model View Presenter (MVP) no Android com um projeto de demonstração simples.

Tempo de leitura: 3 minutes

Model-view-presenter (MVP) é uma derivação do padrão arquitetônico model-view-controller (MVC) que é usado principalmente para construir interfaces de usuário. No MVP, o apresentador assume a funcionalidade de “intermediário”. No MVP, toda a lógica de apresentação é enviada ao apresentador. O MVP defende a separação da lógica de negócios e persistência da atividade e do fragmento

 

Diferenças entre MVC e MVP

Model View Controller

  • Os controladores são baseados em comportamento e podem compartilhar várias visualizações.
  • View pode se comunicar diretamente com o modelo

Model View Presenter

  • Veja mais separado do modelo. O Apresentador é o mediador entre o Modelo e a Visualização.
  • Mais fácil de criar testes de unidade
  • Geralmente, há um mapeamento um para um entre Visualização e Apresentador, com a possibilidade de usar vários Apresentadores para Visualizações complexas
  • Ouça a ação do usuário e as atualizações do modelo
  • Atualiza o modelo e a visualização também

 

Model

Em um aplicativo com uma boa arquitetura em camadas, esse modelo seria apenas a porta de entrada para a camada de domínio ou lógica de negócios. Veja-o como o provedor dos dados que queremos exibir na visualização. As responsabilidades do modelo incluem o uso de APIs, armazenamento de dados em cache, gerenciamento de bancos de dados e assim por diante.

View

A Visualização, geralmente implementada por uma Atividade, conterá uma referência ao apresentador. A única coisa que a visualização fará é chamar um método do Presenter sempre que houver uma ação de interface.

Presenter

O Apresentador é responsável por atuar como intermediário entre a Visualização e o Modelo. Ele recupera dados do Modelo e os retorna formatados para a Visualização. Mas, ao contrário do MVC típico, ele também decide o que acontece quando você interage com o View.

 

Fluxo de Trabalho Simples do Projeto

Aqui, tento ilustrar o básico do padrão MVP com um projeto android de demonstração simples que está disponível no GITHUB. O projeto possui apenas uma tela que possui o nome de usuário e e-mail EditText e uma TextView. Quando o usuário tenta inserir nome de usuário ou e-mail, os dados de entrada serão mostrados na parte superior da tela em TextView.

MainActivityPresenter.java

Aqui, MainActivityPresenter.java funciona como um intermediário entre a visualização e o modelo. Ele escuta a ação do usuário, atualiza o modelo de dados e a visualização.

public class MainActivityPresenter {

    private User user;
    private View view;

    public MainActivityPresenter(View view) {
        this.user = new User();
        this.view = view;
    }

    public void updateFullName(String fullName){
        user.setFullName(fullName);
        view.updateUserInfoTextView(user.toString());

    }

    public void updateEmail(String email){
        user.setEmail(email);
        view.updateUserInfoTextView(user.toString());

    }

    public interface View{

        void updateUserInfoTextView(String info);
        void showProgressBar();
        void hideProgressBar();

    }
}

User.java

public class User {

    private String fullName = "", email = "";

    public User() {
    }

    public User(String fullName, String email) {
        this.fullName = fullName;
        this.email = email;
    }

    public String getFullName() {
        return fullName;
    }

    public void setFullName(String fullName) {
        this.fullName = fullName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "Email : " + email + "\nFullName : " + fullName;
    }
}

MainActivity.java

Em primeiro lugar, esta atividade implementa a Interface MainActivityPresenter.View, por meio da qual o método substituído será chamado. Em segundo lugar, temos que criar o objeto MainActivityPresenter com visão como um construtor. Usamos este objeto apresentador para ouvir a entrada do usuário e atualizar os dados, bem como visualizar.

public class MainActivity extends AppCompatActivity implements MainActivityPresenter.View {

    private MainActivityPresenter presenter;
    private TextView myTextView;
    private ProgressBar progressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        presenter = new MainActivityPresenter(this);

        myTextView = findViewById(R.id.myTextView);
        EditText userName = findViewById(R.id.username);
        EditText email = findViewById(R.id.email);
        initProgressBar();


        userName.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                presenter.updateFullName(s.toString());
            }

            @Override
            public void afterTextChanged(Editable s) {
                hideProgressBar();
            }
        });

        email.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                presenter.updateEmail(s.toString());
            }

            @Override
            public void afterTextChanged(Editable s) {
                hideProgressBar();
            }
        });

    }

    private void initProgressBar() {
        progressBar = new ProgressBar(this, null, android.R.attr.progressBarStyleSmall);
        progressBar.setIndeterminate(true);
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(Resources.getSystem().getDisplayMetrics().widthPixels,
                250);
        params.addRule(RelativeLayout.CENTER_IN_PARENT);
        this.addContentView(progressBar, params);
        showProgressBar();
    }

    @Override
    public void updateUserInfoTextView(String info) {
        myTextView.setText(info);
    }

    @Override
    public void showProgressBar() {
        progressBar.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideProgressBar() {
        progressBar.setVisibility(View.INVISIBLE);
    }
}

Resultado: