Model–view–presenter (MVP) est une dérivation du modèle architectural modèle – vue – contrôleur (MVC) principalement utilisé pour la création d'interfaces utilisateur. Dans MVP, le présentateur assume les fonctionnalités de «l’intermédiaire». Dans MVP, toute la logique de présentation est poussée au présentateur. MVP préconise de séparer la logique métier et la logique de persistance de l'activité et du fragment

Différences entre MVC et MVP

Modèle Vue Contrôleur (MVC)

     Les contrôleurs sont basés sur le comportement et peuvent partager plusieurs vues.
     View peut communiquer directement avec Model

Présentateur de modèle (MVP)

     Voir plus séparé du modèle. Le présentateur est le médiateur entre le modèle et la vue.
     Plus facile à créer des tests unitaires
     En règle générale, il existe un mappage univoque entre View et Presenter, avec la possibilité d’utiliser plusieurs présentateurs pour des vues complexes.
     Écouter l'action de l'utilisateur et les mises à jour du modèle

    Met à jour le modèle et la vue ainsi

Modèle

Dans une application avec une bonne architecture en couches, ce modèle ne serait que la passerelle vers la couche de domaine ou la logique métier. Voyez-le en tant que fournisseur des données que vous souhaitez afficher dans la vue. Les responsabilités du modèle incluent l’utilisation des API, la mise en cache des données, la gestion des bases de données, etc.

Vue

La vue, généralement implémentée par une activité, contiendra une référence au présentateur. La seule chose à faire est d'appeler une méthode de Presenter chaque fois qu'il y a une action d'interface.


Présentateur

Le présentateur est responsable d'agir en tant qu'intermédiaire entre View et Model. Il extrait les données du modèle et les retourne dans la vue. Mais contrairement au MVC typique, il décide également de ce qui se passe lorsque vous interagissez avec la vue.

Partie du projet

Ici, j’essaie d’illustrer les bases du modèle MVP avec un simple projet de démonstration android disponible dans GITHUB. Le projet comporte un seul écran comportant le nom d'utilisateur et l'adresse de messagerie EditText et un TextView. Lorsque l'utilisateur tente de saisir un nom d'utilisateur ou un courrier électronique, les données saisies seront affichées en haut de l'écran dans TextView.

MainActivityPresenter.java

Ici, MainActivityPresenter.java fonctionne comme un intermédiaire entre la vue et le modèle. Il écoute l'action de l'utilisateur, met à jour le modèle de données et la vue.

  1. public class MainActivityPresenter {
  2.  
  3. private User user;
  4. private View view;
  5.  
  6. public MainActivityPresenter(View view) {
  7. this.user = new User();
  8. this.view = view;
  9. }
  10.  
  11. public void updateFullName(String fullName){
  12. user.setFullName(fullName);
  13. view.updateUserInfoTextView(user.toString());
  14.  
  15. }
  16.  
  17. public void updateEmail(String email){
  18. user.setEmail(email);
  19. view.updateUserInfoTextView(user.toString());
  20.  
  21. }
  22.  
  23. public interface View{
  24.  
  25. void updateUserInfoTextView(String info);
  26. void showProgressBar();
  27. void hideProgressBar();
  28.  
  29. }
  30. }

User.java

  1. public class User {
  2.  
  3. private String fullName = "", email = "";
  4.  
  5. public User() {
  6. }
  7.  
  8. public User(String fullName, String email) {
  9. this.fullName = fullName;
  10. this.email = email;
  11. }
  12.  
  13. public String getFullName() {
  14. return fullName;
  15. }
  16.  
  17. public void setFullName(String fullName) {
  18. this.fullName = fullName;
  19. }
  20.  
  21. public String getEmail() {
  22. return email;
  23. }
  24.  
  25. public void setEmail(String email) {
  26. this.email = email;
  27. }
  28.  
  29. @Override
  30. public String toString() {
  31. return "Email : " + email + "\nFullName : " + fullName;
  32. }
  33. }

MainActivity.java

Tout d’abord, cette activité implémente l’interface MainActivityPresenter.View par laquelle sa méthode surchargée sera appelée. Deuxièmement, nous devons créer l'objet MainActivityPresenter avec la vue en tant que constructeur. Nous utilisons cet objet présentateur pour écouter les entrées de l'utilisateur et mettre à jour les données ainsi que la vue.

  1. public class MainActivity extends AppCompatActivity implements MainActivityPresenter.View {
  2.  
  3. private MainActivityPresenter presenter;
  4. private TextView myTextView;
  5. private ProgressBar progressBar;
  6.  
  7. @Override
  8. protected void onCreate(Bundle savedInstanceState) {
  9. super.onCreate(savedInstanceState);
  10. setContentView(R.layout.activity_main);
  11. Toolbar toolbar = findViewById(R.id.toolbar);
  12. setSupportActionBar(toolbar);
  13.  
  14. presenter = new MainActivityPresenter(this);
  15.  
  16. myTextView = findViewById(R.id.myTextView);
  17. EditText userName = findViewById(R.id.username);
  18. EditText email = findViewById(R.id.email);
  19. initProgressBar();
  20.  
  21.  
  22. userName.addTextChangedListener(new TextWatcher() {
  23. @Override
  24. public void beforeTextChanged(CharSequence s, int start, int count, int after) {
  25. }
  26.  
  27. @Override
  28. public void onTextChanged(CharSequence s, int start, int before, int count) {
  29. presenter.updateFullName(s.toString());
  30. }
  31.  
  32. @Override
  33. public void afterTextChanged(Editable s) {
  34. hideProgressBar();
  35. }
  36. });
  37.  
  38. email.addTextChangedListener(new TextWatcher() {
  39. @Override
  40. public void beforeTextChanged(CharSequence s, int start, int count, int after) {
  41. }
  42.  
  43. @Override
  44. public void onTextChanged(CharSequence s, int start, int before, int count) {
  45. presenter.updateEmail(s.toString());
  46. }
  47.  
  48. @Override
  49. public void afterTextChanged(Editable s) {
  50. hideProgressBar();
  51. }
  52. });
  53.  
  54. }
  55.  
  56. private void initProgressBar() {
  57. progressBar = new ProgressBar(this, null, android.R.attr.progressBarStyleSmall);
  58. progressBar.setIndeterminate(true);
  59. RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(Resources.getSystem().getDisplayMetrics().widthPixels,
  60. 250);
  61. params.addRule(RelativeLayout.CENTER_IN_PARENT);
  62. this.addContentView(progressBar, params);
  63. showProgressBar();
  64. }
  65.  
  66. @Override
  67. public void updateUserInfoTextView(String info) {
  68. myTextView.setText(info);
  69. }
  70.  
  71. @Override
  72. public void showProgressBar() {
  73. progressBar.setVisibility(View.VISIBLE);
  74. }
  75.  
  76. @Override
  77. public void hideProgressBar() {
  78. progressBar.setVisibility(View.INVISIBLE);
  79. }
  80. }