JavaRush /Blog Java /Random-FR /MVP sur Android pour les plus petits

MVP sur Android pour les plus petits

Publié dans le groupe Random-FR
Lorsque j'ai commencé mon parcours en tant que développeur Android, les mots « Architecture d'applications mobiles » m'ont profondément perplexe, Google et les articles sur Habré m'ont plongé dans une dépression encore plus grande - je regarde le livre et je ne vois rien. Je pense que si vous lisez cet article, vous avez déjà étudié cette image plus d'une fois et essayé de comprendre ce qui se passe : MVP sur Android pour les plus petits - 1le problème de la compréhension de l'approche architecturale dans le développement mobile, à mon avis, réside dans l'abstraction de l'architecture elle-même. Chaque développeur a sa propre vision de la manière de mettre en œuvre correctement tel ou tel modèle. Des exemples plus ou moins décents de mise en œuvre de MVP ont été trouvés dans le secteur anglophone d'Internet, ce qui n'est pas surprenant. Regardons brièvement ce que c'est et passons à un exemple. Modèle - niveau de données. Je n'aime pas utiliser le terme « logique métier », donc dans mes applications je l'appelle Repository et il communique avec la base de données et le réseau. Vue — niveau d'affichage. Ce sera Activity , Fragment ou Custom View si vous n'aimez pas danser avec un tambourin et interagir avec le cycle de vie. Permettez-moi de vous rappeler qu'au départ, toutes les applications Android sont subordonnées à la structure MVC , où le contrôleur est une activité ou un fragment . Presenter est une couche entre View et Model. View transmet les événements qui lui surviennent, le présentateur les traite, si nécessaire, accède au Modèle et renvoie les données à la View pour le rendu. En ce qui concerne Android et un exemple spécifique, je soulignerai la partie importante : le contrat. Il s'agit de l'interface qui décrit toutes les interactions entre les composants ci-dessus. Pour résumer la partie théorique :
  • View connaît Presenter ;
  • Le présentateur connaît la vue et le modèle (référentiel) ;
  • Modèle seul ;
  • Le contrat régit les interactions entre eux.
En fait, l'exemple lui-même, pour la simplicité de l'expérience, en cliquant sur un bouton, nous allons charger une ligne de la base de données et l'afficher dans un TextView . Par exemple, la base de données contient une liste des meilleurs restaurants de la ville. Commençons par le contrat : Créons une interface MainContract:
public interface MainContract {
    interface View {
        void showText();
    }

    interface Presenter {
        void onButtonWasClicked();
        void onDestroy();
    }

    interface Repository {
        String loadMessage();
    }
}
Pour l’instant, nous mettons simplement en avant les 3 composants de notre future application et ce qu’ils feront. Nous décrirons ensuite le référentiel :
public class MainRepository implements MainContract.Repository {

    private static final String TAG = "MainRepository";
    @Override
    public String loadMessage() {
        Log.d(TAG, "loadMessage()");
        /** Здесь обращаемся к БД or сети.
         * Я специально ничего не пишу, чтобы не загромождать пример
         * DBHelper'ами и прочими не относяшимеся к теме an objectми.
         * Поэтому я буду возвращать строку Сосисочная =)
         */
        return "Сосисочная у Лёхи»;
    }
}
Tout est clair avec, il suffit de charger et de décharger des données. La prochaine étape est le présentateur :
public class MainPresenter implements MainContract.Presenter {
    private static final String TAG = "MainPresenter";

    //Компоненты MVP applications
    private MainContract.View mView;
    private MainContract.Repository mRepository;

    //Сообщение
    private String message;


    //Обрати внимание на аргументы конструктора - мы передаем экземпляр View, а Repository просто создаём конструктором.
    public MainPresenter(MainContract.View mView) {
        this.mView = mView;
        this.mRepository = new MainRepository();
        Log.d(TAG, "Constructor");
    }

    //View сообщает, что кнопка была нажата
    @Override
    public void onButtonWasClicked() {
        message = mRepository.loadMessage();
        mView.showText(message);
        Log.d(TAG, "onButtonWasClicked()");
    }

    @Override
    public void onDestroy() {
        /**
         * Если бы мы работали например с RxJava, в этом классе стоило бы отписываться от подписок
         * Кроме того, при работе с другими методами асинхронного андроида,здесь мы боремся с утечкой контекста
         */

        Log.d(TAG, "onDestroy()");
    }
}
Vous souvenez-vous que j'ai écrit sur la danse avec un tambourin et le cycle de la vie ? Le Presenter vit aussi longtemps que sa View, lors du développement de scénarios utilisateur complexes, je vous conseille de dupliquer tous les rappels View dans le Presenter et de les appeler aux moments appropriés, en dupliquant le cycle de vie Activité/Fragment, afin de comprendre à temps quels sont les besoins en finir avec les données qui traînent actuellement dans « l’intercalaire ». Et enfin, voir :
public class MainActivity extends AppCompatActivity implements MainContract.View {

    private static final String TAG = "MainActivity";

    private MainContract.Presenter mPresenter;

    private Button mButton;

    private TextView myTv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Создаём Presenter и в аргументе передаём ему this - эта Activity расширяет интерфейс MainContract.View
        mPresenter = new MainPresenter(this);

        myTv = (TextView) findViewById(R.id.text_view);
        mButton = (Button) findViewById(R.id.button);

        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mPresenter.onButtonWasClicked();
            }
        });
        Log.d(TAG, "onCreate()");
    }

    @Override
    public void showText(String message) {
        myTv.setText(message);
        Log.d(TAG, "showMessage()");
    }

    //Вызываем у Presenter метод onDestroy, чтобы избежать утечек контекста и прочих неприятностей.
    @Override
    public void onDestroy() {
        super.onDestroy();
        mPresenter.onDestroy();
        Log.d(TAG, "onDestroy()");
    }
}
Que se passe-t-il?
  • L'activité, également connue sous le nom de View, onCreate()crée une instance Presenter dans une méthode et se transmet à son constructeur.
  • Lorsqu'un présentateur est créé, il reçoit explicitement une vue et crée une instance de référentiel (d'ailleurs, il peut devenir un Singleton)
  • Lorsqu'un bouton est enfoncé, la vue frappe le présentateur et dit : « Le bouton a été enfoncé. »
  • Le présentateur se tourne vers Repository : "Téléchargez cette merde pour moi."
  • Le référentiel charge et livre les « trucs » au présentateur.
  • Le présentateur se tourne vers View : « Voici les données pour vous, dessinez-les »
C'est tout, les gars. PS Il est important de délimiter clairement les responsabilités entre les composantes. Par exemple, dans un de mes projets de formation, en cliquant sur un bouton, il était nécessaire de modifier des données dans la base de données. Le modèle a été décrit par une classe POJO, j'ai transmis des informations sur l'emplacement de la vue, qui est responsable des informations sur l'objet à l'écran, le présentateur a recherché cet objet dans la liste et l'a envoyé pour qu'il soit écrit dans le référentiel. Tout vous semble-t-il logique ? Mais mon mentor a souligné ce qui suit : le référentiel ne doit QUE faire de l'écriture et de la lecture, il ne doit pas extraire les informations nécessaires du POJO et décider de ce qu'il doit écrire. Le Présentateur doit lui donner uniquement les informations à enregistrer et rien de plus. Il n'existe pas de cadre strict pour la mise en œuvre de l'architecture : expérimentez, essayez, cherchez ce qui vous convient personnellement. Et n'oubliez pas de montrer à vos camarades seniors la révision du code =) L'exemple est disponible sur GitHub : https://github.com/admitrevskiy/MVP_Example
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION