Normalmente, con Java, creamos una interfaz *Contract para manejar la interacción entre View y Presenter , como:
Actividad principal
como View
public class MainActivity extends Activity implements MainContract { @Override public void onCreate(Bundle b) { presenter.requestData(); } @Override public void showData(String data) { // Handle data ... } Presentador principal
como Presenter
public class MainPresenter { public void requestData() { contract.showData("data"); } } Contrato principal
como interface
public interface MainContract { void showData(String data); }Dado que Kotlin tiene la función "Función de orden superior" , ¿ deberíamos simplemente pasar funciones para manejar la interacción entre la vista y el presentador? Puede ser algo como:
Vista:
presenter.requestData { data -> // Handle data }Presentador:
fun requestData(handler: (String) -> Unit) { handler("data") }No estoy preguntando sobre la posibilidad, estoy preguntando si es una mejor práctica o no.
La respuesta a esta pregunta está más relacionada con las decisiones arquitectónicas que con las limitaciones técnicas. Podría implementar lo mismo en Java (incluso en Java7) con instancias anónimas (concedido que tendría mucho más repetitivo y sería más difícil de leer).
La idea de MVP para tener un contrato que implementa la vista es que cada presentador sepa cómo obtener, manipular y presentar dicho contrato. Potencialmente, una vista puede implementar múltiples contratos y tener múltiples presentadores. Además, cada instancia de presentador solo funciona con una implementación del contrato, pero podría tener dos instancias que sirvan a dos implementaciones diferentes.
Si en lugar de que cada vista se ajuste a los contratos de cada presentador, cada llamada del presentador toma una lambda, tarde o temprano terminará enfrentando un problema.
Por ejemplo, imagine un presentador que obtiene datos de forma asíncrona y los almacena en caché en la memoria:
fetchData() .showLoading() del contrato.hideLoading() y showData(data) del contrato.fetchData() nuevamenteshowData() con los datos almacenados en cachéEn este caso, si usamos lambdas en lugar de un contrato, necesitaríamos solicitar dos lambdas diferentes en el mismo método: una para cuando está en caché y otra para cuando no lo está. También estamos acoplando la implementación de la vista al presentador; en el futuro, es posible que otra implementación de la interfaz del presentador no necesite estas dos lambdas porque la lógica ha cambiado.
Es importante recordar que en MVP, idealmente, tanto la vista como el presentador se comunican entre sí a través de interfaces y, en este caso, la interfaz del presentador no debe verse influenciada por los detalles de implementación y solo exponer qué acciones pueden realizar.