interactor - Android MVP actividad abierta desde el presentador, anti-patrón?
mvvm android (3)
Como escribí en mi comentario a la respuesta aceptada , creo que administrar la navegación desde la capa de vista es una clara regla de romper la separación de las preocupaciones: las vistas deben contener SOLO métodos para actualizar la pantalla de la interfaz de usuario actual.
El problema se origina en el diseño de la plataforma Android, ya que las clases de Activity
y Fragment
contienen ambos métodos para operar en la pantalla de la interfaz de usuario y para enviar objetos de intención que inician otras actividades como startActivity
.
Una forma limpia de resolver esto sería crear una interfaz de Navigator
que contendría métodos relacionados con la navegación, hacer que las actividades lo implementen e inyectarlo también en los presentadores. De esta manera, al menos desde el punto de vista de los presentadores, la navegación y la manipulación de la interfaz de usuario se separarán. Sin embargo, puede parecer extraño desde el punto de vista de las actividades: ahora, con frecuencia, implementarían ambas interfaces (Navegador y Vista) y pasarían su referencia 2 veces al presentador. Si por este motivo decide administrar la navegación desde su capa de vista, al menos mantenga los métodos para navegar separados de los de la interfaz de usuario: nunca realice la navegación ni la manipulación de la interfaz de usuario en el mismo método.
¿Sería un antipatrón si desde una capa de Presenter abro una Activity
?
Si es así, ¿debo gestionar la navegación de la aplicación desde la capa de visualización?
En mi opinión, sería mejor si abre una actividad desde la capa de visualización. Prefiero que el presentador sepa lo menos posible sobre la actividad.
Si existe alguna condición sobre qué actividad debe iniciarse, puede usar algo como esto:
public class Presenter {
private ViewsPresentation mViewsPresentation;
public void someButtonClicked() {
if (/*some condition*/) {
mViewsPresentation.startFirstActivity();
} else {
mViewsPresentation.startSecondActivity();
}
}
public interface ViewsPresentation {
void startFirstActivity();
void startSecondActivity();
}
}
Sí, es un patrón anti-mvp. Basado en la vista pasiva en MVP, perdiste tu capacidad de prueba, porque no tienes que lidiar con el marco de Android en tu presentador.
Por lo tanto, es mejor administrar la navegación de la aplicación desde la capa de visualización.
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();
}
}
También otra ventaja de esta manera es que será fácil reemplazar la actividad con un fragmento o una vista.
Edición 1:
Morgwai dijo que esta manera romperá la separación de la preocupación y la responsabilidad única, pero no se puede tener una responsabilidad única en todas Morgwai . En algún momento necesitas violarlo. Aquí hay un ejemplo de Google para MVP:
TaskDetailPresenter
llama a ShowEditTask
que es responsable de abrir una nueva Activity
dentro de TaskDetailFragment
.
Pero también puedes usar CommandPattern que es un mejor enfoque
interface NavigationCommand {
void navigate();
}
Entonces, Presenter lo usará cuando lo necesite.