miércoles, 11 de diciembre de 2013

Desarrollar en Android apesta.

Pues sí, últimamente estamos de diatriba. Será el frío del invierno que me cabrea...



Diseño penoso.

Android "quiere" seguir un patrón MVC pero, por diseño, el estado, el ciclo de vida, el negocio y la lógica de vista están generalmente demasiado acoplados en las actividades. Esto hace más difícil la pruebas unitarias y es complicado obedecer al principio de responsabilidad individual. 

Hay que heredar de clases del framework para casi cualquier cosa, y aun así tienes que reescribir prácticamente la clase entera para hacer algo que no sea lo más básico y cutre del mundo.

El punto de entrada a una aplicación tiene que ser una actividad, por lo que es un infierno tener un "navegador/controlador" que se ocupe de controlar a que actividad se debe ir dependiendo de la respuesta de la actividad actualmente en primer plano. Además sólo una actividad tiene métodos para lanzar otra actividad.

Todo lo de arriba significa que implementar Inyección de dependencias es un trabajo titánico.

La comunicación "interna" se basa también en Intent. Los intent están bien para llamar a una tarea externa como la cámara de fotos y que te retorne una imagen a tu actividad, pero por el amor de dios ¿Intent "internos" para la comunicación entre mis actividades? Y encima el paso de información no está fuertemente tipado, por lo que en una aplicación grande terminas con decenas de intent tratando de controlar quién manda a quién y qué es lo que manda. Los tipos no primitivos tienen que ser serializados para poder mandarse por los intent, por lo que olvídate de crear clases que necesiten un grafo de referencias más o menos complejo.

Hacer una triste vista dinámica requieren una cantidad de código absurda.

La API de Java de Android da sensación de estar incompleta y de haber sido chapuceada un poco para que se puedan hacer aplicaciones con ella, a duras penas reaprovechando la idea de los Intent entre actividades. La herencia de la API es caótica: Una activity hereda de 2 wrapers, para modificar su comportamiento en caso de ser necesario; y estos a su vez heredan de Context. Por otra parte, está la clase Application, que también hereda de un wrapper que hereda de Context. Encontrar el "punto de entrada" a partir del cual puedes empezar a acceder a las clases definidas por la API, para llamar a otros métodos, es también un infierno ideado, cuanto menos, por Cenobitas frustrados por impotencia sexual.

Esta estructura sólo la he visto en código fuente de aplicaciones hechas a salto de mata, en las que se ha necesitado heredar de nuevo de una clase para poder trabajar con ella, porque hacerlo "bien" requeriría reestructurar la arquitectura de la aplicación (las dependencias, el acoplamiento de clases y el paso de mensajes de una a otra) en un momento en el que no hay tiempo ni ganas.

Según yo lo veo, una Aplicación TIENE un Context (entre otras cosas) y se compone de una o varias Activity (en el contexto de una aplicación con UI, dejemos aparte el tema de los broadcast y los servicios de momento...). ¿Por qué en la API de Android una Application ES un Context? ¿Por qué una Activity ES un Context sin ser una Application? ¿Por qué el punto de entrada tiene que ser una Activity? Tengo que "escalar" por la API y la herencia hacia arriba para luego "bajar" de nuevo en otra Activity. Terrible...

Señores de Google, no quiero que mi aplicación sea un puñado de actividades sueltas. Quiero un contexto coherente y fuertemente tipado para toda mi arquitectura.

Quiero una clase base Aplicación de la cual heredar como punto de entrada. Esta clase será inicializada por el sistema y luego se ejecutará el código personalizado de la clase hija. El sistema se encargará del ciclo de vida de esta clase. Y la clase Aplicación se encargara del ciclo de vida de las Actividades.

Quiero una o varias interfaces en la API que me permitan exponer las Actividades de mi Aplicación como receptoras de un Intent, completamente independiente de la interfaz propia para el manejo que hace mi Aplicación de mis Actividades.

Quiero un contenedor de inyección de dependencias integrado en el sistema que yo pueda configurar en tiempo de diseño o en tiempo de ejecución, que se encargue de inyectar las Actividades y toda la cadena de dependencias (controladores, modelos de vista, clases de negocio, persistencia, entidades, etc) a la Aplicación.

Quiero programación orientada a aspectos...

1 comentario:

  1. La verdad es que cuando he estado aprendiendo a desarrollar para android (en plan autodidacta) he tenido sensaciones muy parecidas a las tuyas.

    Preparar un interfaz es un dolor de huevos en cuanto te sales un poco de las estructuras básicas, nunca termine de tener claro cual era la forma apropiada de acceder a las variables que tenía en el contexto en cada ocasión, si quieres usar una base de datos te tienes que currar los scripts de creación dentro de la aplicación y si tienes datos iniciales sólo los puedes incluír como 'INSERTS' junto con los scripts de creación... y un largo etcétera de cuestiones que me resultaban muy extrañas.

    Lo que no sabía es que ésta arquitectura pretendía ser un MVC... vamos, desde mi ignorancia... poco menos que es de risa decir que es MVC...

    A mi siempre me ha parecido una programación orientada a eventos, dónde lo que manda no es el usuario, sino el dispositivo, que puede hacer cosas por si mismo interrumpiendo tu actividad. Luego además el tema de los 'intent para todo' y la idea que hay detrás de reutilización y de que un recurso pueda ser tratado por diferentes aplicaciones, es una buena idea pero el precio que paga el programador para mantener ésa idea... no sé si vale la pena...

    En fin en su momento yo pensaba que 'si un montón de gente brillante ha parido ésto, será la opción menos mala para poder contemplar todas las eventualidades que pueden suceder en un teléfono', pero tampoco me convencía.

    ResponderEliminar