26 votes

MVP Android : Activité ouverte à partir du présentateur, anti-modèle ?

Serait-ce un anti-modèle si, à partir d'un calque du présentateur, j'ouvrais un fichier Activity ?

Si oui, dois-je gérer la navigation de l'application à partir de la couche de visualisation ?

29voto

Saeed Masoumi Points 4676

Oui, c'est un modèle anti-mvp. Basé sur vue passive en MVP, vous avez perdu votre testabilité, car vous n'avez pas à vous occuper du framework Android dans votre présentateur.

Il est donc préférable de gérer la navigation de l'application à partir de la couche de visualisation.

class MyPresenter {
    MyPresenter.View view;

    void backButtonClicked() {
        view.navigateToHomeScreen();
    }

    public interface View {
        void navigateToHomeScreen();
    }
}

class MyActivity extends Activity implements MyPresenter.View {
    @Override
    void navigateToHomeScreen() {
        startActivity(...)
    }

    @OnClick(R.id.my_button)
    void onClick() {
        presenter.backButtonClicked();
    }
} 

Un autre avantage de cette méthode est qu'il sera facile de remplacer une activité par un fragment ou une vue.

Edit 1 :

Morgwai En disant cela, on brise la séparation des préoccupations et la responsabilité unique, mais on ne peut pas avoir une responsabilité unique partout. Il faut parfois la violer. Voici un exemple de Google pour MVP :

TaskDetailPresenter appelle ShowEditTask qui est responsable de l'ouverture d'une nouvelle Activity à l'intérieur de TaskDetailFragment .

Mais vous pouvez aussi utiliser Modèle de commande quelle est la meilleure approche

interface NavigationCommand {
    void navigate();
}

Ainsi, Presenter l'utilisera quand il en aura besoin.

9voto

morgwai Points 81

Comme je l'ai écrit dans mon commentaire sur le réponse acceptée Je pense que la gestion de la navigation à partir de la couche de visualisation constitue une violation manifeste de la règle de séparation des préoccupations : les vues ne doivent contenir QUE des méthodes permettant de mettre à jour l'écran actuel de l'interface utilisateur.

Le problème provient de la conception de la plateforme Android, car Activity y Fragment Les classes contiennent à la fois des méthodes permettant d'agir sur l'écran de l'interface utilisateur et d'envoyer des objets d'intention qui lancent d'autres activités telles que startActivity .

Une manière propre de résoudre ce problème serait de créer des Navigator qui contiendrait des méthodes liées à la navigation, faire en sorte que les activités l'implémentent et l'injecter dans les présentateurs également. De cette façon, au moins du point de vue des présentateurs, la navigation et la manipulation de l'interface utilisateur seraient séparées. Cela peut toutefois sembler étrange du point de vue des activités : elles implémenteraient souvent les deux interfaces (Navigator et View) et passeraient leur référence deux fois au présentateur. Si, pour cette raison, vous décidez de gérer la navigation à partir de votre couche de vue, gardez au moins les méthodes de navigation séparées de celles de manipulation de l'interface utilisateur : n'effectuez jamais la navigation et la manipulation de l'interface utilisateur dans la même méthode.

5voto

Alexander Points 16

À mon avis, il serait préférable d'ouvrir une activité à partir de la couche de visualisation. Je préfère que Presenter connaisse l'activité le moins possible.

Si l'activité à lancer est soumise à certaines conditions, vous pouvez utiliser quelque chose comme ceci :

public class Presenter {

    private ViewsPresentation mViewsPresentation;

    public void someButtonClicked() {
        if (/*some condition*/) {
            mViewsPresentation.startFirstActivity();
        } else {
            mViewsPresentation.startSecondActivity();
        }
    }

    public interface ViewsPresentation {
        void startFirstActivity();
        void startSecondActivity();
    }

}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X