Siempre que trabajo con código GUI, el código tiende a hincharse más rápido que otros tipos de código. También parece más difícil de refactorizar. Mientras que en otros tipos de código puedo refactorizar con bastante facilidad, encuentro que puedo descomponer una clase más grande en piezas más pequeñas de funcionalidad, con la mayoría de los marcos de GUI a menudo estoy vinculado a un marco que requiere mi widget / control / cualquier clase para implementar muchas más cosas más directamente en el widget / control / lo que sea. A veces esto se debe a la necesidad de (a) heredar de algún widget / control / cosa base o (b) necesitar acceso a métodos protegidos.
Por lo general, también tengo que, por ejemplo, responder a una gran variedad de entradas a través de señales / eventos / lo que sea del marco para implementar todos los modos de interacción con el usuario. Es posible que necesite en un control / widget GUI para manejar una gran variedad de entradas / salidas que pueden incluir:
- un clic derecho / menú contextual
- reaccionando a las selecciones del menú contextual, que pueden ser muchas
- una forma especial de pintar la GUI
- reaccionar a la entrada del teclado
- botones, casillas de verificación,
- etcétera etcétera
... todo el tiempo gestiona las clases bajo la GUI que representa la lógica empresarial.
Una GUI simple y directa puede hacer que su código crezca bastante rápido, incluso cuando separa la lógica de negocios y usa MVC, encuentro que el código GUI es un gran imán para el cambio.
¿Hay alguna forma de administrar el código GUI de una manera sensata y evitar que se convierta en una ventana rota? ¿O es una masa de controladores de eventos aleatorios / métodos anulados realmente lo mejor que podemos hacer para el código GUI?
fuente
Respuestas:
Lo que hay que recordar sobre el código GUI es que está controlado por eventos, y el código controlado por eventos siempre tendrá la apariencia de una masa de controladores de eventos organizados al azar. Donde se vuelve realmente desordenado es cuando tratas de calzar el código no controlado por eventos en la clase. Claro, tiene la apariencia de proporcionar soporte para los controladores de eventos y puede mantener sus controladores de eventos agradables y pequeños, pero todo ese código de soporte adicional flotando hace que su fuente de GUI parezca hinchada y desordenada.
Entonces, ¿qué puede hacer al respecto y cómo puede hacer que las cosas sean más fáciles de refactorizar? Bueno, primero cambiaría mi definición de refactorización de algo que hago ocasionalmente a algo que hago continuamente mientras codifico. ¿Por qué? Porque desea refactorizar para permitirle modificar más fácilmente su código, y no al revés. No solo le pido que cambie la semántica aquí, sino que le pido que haga un poco de calistenia mental para ver su código de manera diferente.
Las tres técnicas de refactorización que considero que uso más comúnmente son Cambiar nombre , Método de extracción y Clase de extracción . Si nunca aprendí una sola refactorización, esas tres aún me permitirían mantener mi código limpio y bien estructurado, y por el contenido de su pregunta, me parece que probablemente se encontrará utilizando las mismas tres refactorizaciones casi constantemente en Para mantener su código GUI delgado y limpio.
Puede tener la mejor separación posible de GUI y lógica de negocios en el mundo, y aún así el código de GUI puede parecer una mina de código que se ha detonado en el medio. Mi consejo es que no está de más tener una o dos clases adicionales para ayudarlo a administrar su GUI correctamente, y esto no necesariamente tiene que ser sus clases de Vista si está aplicando el patrón MVC, aunque con frecuencia encontrará las clases intermedias son tan similares a su punto de vista que a menudo sentirá la necesidad de fusionarlas por conveniencia. Mi opinión sobre esto es que realmente no está de más agregar una capa adicional específica de GUI para administrar toda la lógica visual, sin embargo, es probable que desee sopesar los beneficios y los costos de hacerlo.
Mi consejo por lo tanto es:
fuente
Creo que muchos de los problemas que está experimentando se remontan a una causa simple. La mayoría de los desarrolladores no tratan el código GUI como un código 'real'. No tengo evidencia o estadísticas aquí, solo mi instinto.
Tal vez piensan que es ' solo presentación ' y no importante. " No hay lógica de negocios allí ", dicen, " ¿ por qué la unidad lo prueba "? Se ríen cuando mencionas la orientación a objetos y escribes código limpio. Ni siquiera INTENTAN mejorar las cosas. Para empezar, no hay una estructura, solo dan un poco de código y lo dejan pudrirse a medida que otros agregan su propio toque con el tiempo. Un hermoso desastre, código de graffiti.
El código GUI tiene sus desafíos únicos, por lo tanto, debe tratarse de manera diferente y con respeto. Necesita amor y desarrolladores que quieran escribirlo. Los que lo mantendrán delgado y le darán una buena estructura y patrones correctos.
fuente
Por alguna razón, el código GUI crea un punto ciego en los desarrolladores sobre la separación de preocupaciones. Tal vez sea porque todos los tutoriales agrupan todo en una clase. Tal vez sea porque la representación física hace que las cosas parezcan más estrechamente acopladas de lo que son. Tal vez sea porque las clases se desarrollan lentamente para que las personas no reconozcan que necesitan una refactorización, como la proverbial rana que se hierve al aumentar lentamente el calor.
Cualquiera sea la razón, la solución es hacer que sus clases sean mucho más pequeñas. Hago esto preguntándome continuamente si es posible poner lo que estoy escribiendo en una clase separada. Si es posible ingresar a otra clase, y puedo pensar en un nombre razonable y simple para esa clase, entonces lo hago.
fuente
Es posible que desee echar un vistazo al modelo Presentador de vista de modelo / Vista pasiva. Ray Ryan dio una buena charla en un Google IO sobre las mejores prácticas de arquitectura para GWT.
http://www.google.com/events/io/2009/sessions/GoogleWebToolkitBestPractices.html
Es fácil abstraer las ideas a otros marcos e idiomas. El principal beneficio de MVP (en mi opinión) es la capacidad de prueba unitaria. Y solo obtienes eso, si tu código no está hinchado y no es espagueti (a juzgar por tu pregunta, esto es lo que quieres). Funciona al introducir una capa de lógica de vista llamada presentador. La vista real se desacopla de esto a través de una interfaz (y, por lo tanto, se puede burlar fácilmente en pruebas unitarias). Ahora, dado que su capa de lógica de vista (el presentador) está libre de los elementos internos del marco de GUI concreto, puede organizarlo como un código normal y no está vinculado, por ejemplo, a la jerarquía de herencia de Swings. Idealmente, podría cambiar las implementaciones de GUI en diferentes marcos, siempre que se ajusten a la misma interfaz.
fuente
Mi respuesta consta de cuatro partes: estructura, simplicidad, pruebas y sintaxis.
¡Los tres primeros son realmente difíciles de hacer!
Estructura significa prestar mucha atención al uso de la menor cantidad de código y la cantidad máxima de marcos, bibliotecas, etc.
La simplicidad significa mantener las cosas simples desde el diseño inicial hasta la implementación real. Mantener la navegación simple, usar complementos simples, mantener el diseño bastante 'simple', todo ayudará aquí. Ahora se pueden 'vender' a clientes / usuarios que pueden ver rápidamente las ventajas de las páginas que funcionan en computadoras, ipad, dispositivos móviles y otros dispositivos.
Probar significa incluir herramientas de prueba de navegador (me vienen a la mente webrat y carpincho con mi trabajo en rieles) que detectan problemas cruzados en el navegador por adelantado cuando se puede diseñar un mejor código para tratarlos al principio en lugar de los frecuentes 'parches' de código por diferentes desarrolladores ya que son 'descubiertos' por usuarios de diferentes navegadores.
Sintaxis. Es realmente útil usar un corrector de código / IDE / plugin de editor, etc. para su HTML, CSS, Javascript, etc. La ventaja que han obtenido los navegadores al manejar HTML mal formado funciona en su contra cuando los diferentes navegadores funcionan de manera diferente con así que es esencial una herramienta que verifique su formato HTML. Tener HTML bien formado es muy útil para tener HTML no bloqueado ya que un código incorrecto debería tener más visibilidad.
fuente
La solución que he encontrado es el código declarativo. El uso de solo código de procedimiento es una receta para el código GUI de espagueti. Claro, una "forma especial de pintar el widget" probablemente seguirá siendo el código. Pero este es un código aislado en una clase. Controladores de eventos, métodos abreviados de teclado, tamaños de ventana: todo lo que es desordenado se declara mejor.
fuente
Hay muchas respuestas geniales aquí.
Una cosa que me ha ayudado a simplificar el código GUI es asegurarme de que la GUI tenga su propio modelo de datos.
Para tomar un ejemplo simple, si tengo una GUI con 4 campos de entrada de texto, entonces tengo una clase de datos separada que mantiene el contenido de esos 4 campos de entrada de texto. Las GUI más complicadas requieren más clases de datos.
Diseño una GUI como modelo - vista. El modelo de GUI es controlado por el controlador de la aplicación del modelo de aplicación - vista - controlador. La vista de la aplicación es el modelo GUI, en lugar del código GUI en sí.
fuente
Las aplicaciones como procesamiento de textos, editores gráficos, etc. tienen interfaces complejas y su código no puede ser simple. Sin embargo, para las aplicaciones comerciales, la GUI no tiene que ser tan compleja, sino más o menos como es.
Algunas de las claves para simplificar la GUI son (la mayoría se aplican a .NET):
Esfuércese por un diseño más simple siempre que sea posible. Evite comportamientos sofisticados si la empresa no lo solicita.
Use un buen proveedor de controles.
No cree la funcionalidad de control personalizado en el código del cliente en sí. En su lugar, cree controles de usuario que extiendan el control original de tal manera que pueda reflejar sus comportamientos específicos en los controles en lugar de en el código del formulario / página en uso.
Use un marco de trabajo (incluso un producto propio) para manejar la internacionalización, la administración de recursos, los estilos, etc. para que no repita este código en cada interfaz de usuario.
Emplear un componente (o marco) para la navegación.
Cree diálogos estándar para errores, advertencias, confirmación, etc.
fuente
Aplique el diseño orientado a objetos a su código y para el desarrollo de la interfaz de usuario:
Aquí hay una aplicación pequeña pero no trivial para ayudar a ilustrar algunos de mis puntos. Puede encontrar el código y ver el diagrama de interacción del modelo aquí: https://github.com/vanfrankie/pushpopbox
fuente
Desea echar un vistazo al concepto de "enlace de datos" . Esta es una forma de conectar elementos de la IU a elementos del modelo abstracto de manera declarativa, de modo que los elementos del modelo se sincronicen automáticamente con el contenido de la IU. Hay muchos beneficios de este enfoque, por ejemplo, no tener que escribir los controladores de eventos usted mismo para sincronizar los datos.
Hay soporte de enlace de datos para muchos marcos de UI, por ejemplo .NET y Eclipse / JFace .
fuente