design - forma - ¿Cómo se planifica la arquitectura de una aplicación antes de escribir cualquier código?
arquitectura hexagonal ejemplo (15)
"Las pizarras blancas, los bocetos y las notas adhesivas son excelentes herramientas de diseño. Las herramientas de modelado complicadas tienden a distraer más que a iluminar". De Practices of an Agile Developer por Venkat Subramaniam y Andy Hunt .
Una cosa con la que lucho es planificar la arquitectura de una aplicación antes de escribir cualquier código.
No me refiero a reunir requisitos para concentrarme en lo que la aplicación necesita hacer, sino más bien a pensar en una buena manera de diseñar las estructuras generales de clase, datos y flujo, e iterar esos pensamientos para que tenga un plan creíble de acción en mente incluso antes de abrir el IDE. Por el momento, es muy fácil abrir el IDE, crear un proyecto en blanco, comenzar a escribir bits y bobs y dejar que el diseño ''crezca'' desde allí.
Creo que UML es una forma de hacer esto, pero no tengo experiencia con él, así que parece algo nebuloso.
¿Cómo se planifica la arquitectura de una aplicación antes de escribir cualquier código? Si UML es el camino a seguir, ¿puede recomendar una introducción concisa y práctica para un desarrollador de aplicaciones pequeñas?
Aprecio tu aporte.
Considero lo siguiente:
- qué se supone que debe hacer el sistema, es decir, cuál es el problema que el sistema está tratando de resolver
- ¿Quién es el cliente y cuáles son sus deseos?
- qué tiene que integrar el sistema con
- ¿Hay algún aspecto heredado que deba ser considerado?
- cuales son las intercursiones del usuario
- etc ...
Luego empiezo a mirar el sistema como una caja negra y:
- ¿Cuáles son las interacciones que deben suceder con esa caja negra?
- ¿Cuáles son los comportamientos que deben ocurrir dentro del recuadro negro, es decir, qué necesita suceder con esas interacciones para que el recuadro negro muestre el comportamiento deseado en un nivel superior, por ejemplo, recibir y procesar mensajes entrantes de un sistema de reservas, actualizar una base de datos, etc. .
Luego, esto comenzará a brindarle una vista del sistema que consta de varios recuadros negros internos, cada uno de los cuales puede desglosarse aún más de la misma manera.
UML es muy bueno para representar ese comportamiento. Puede describir la mayoría de los sistemas simplemente usando dos de los muchos componentes de UML, a saber:
- diagramas de clase, y
- diagramas de secuencia.
Es posible que también necesite diagramas de actividad si existe algún paralelismo en el comportamiento que deba describirse.
Un buen recurso para aprender UML es el excelente libro de Martin Fowler "UML Distilled" ( enlace de Amazon - desinfectado para el script kiddie link nazis por ahí (-:). Este libro le da una mirada rápida a las partes esenciales de cada uno de los componentes de UML.
Oh. Lo que describí es más o menos el enfoque de Ivar Jacobson. Jacobson es uno de los tres amigos de OO. De hecho, UML fue desarrollado inicialmente por las otras dos personas que forman los Tres Amigos, Grady Booch y Jim Rumbaugh
Definitivamente debería echarle un vistazo al Código Completo de Steve McConnell, y especialmente en su capítulo de regalo sobre "Diseño en Construcción".
Puedes descargarlo desde su sitio web:
He estado haciendo arquitectura por un tiempo. ¡Utilizo BPML para refinar primero el proceso comercial y luego uso UML para capturar varios detalles! ¡El tercer paso generalmente es ERD! Cuando hayas terminado con BPML y UML, tu ERD será bastante estable. Ningún plan es perfecto y ninguna abstracción será 100%. ¡Planifique la refactorización, el objetivo es minimizar la refactorización tanto como sea posible!
Intento dividir mi pensamiento en dos áreas: una representación de las cosas que intento manipular y lo que pretendo hacer con ellas.
Cuando trato de modelar las cosas que trato de manipular, se me ocurre una serie de definiciones de artículos discretos: un sitio de comercio electrónico tendrá una SKU, un producto, un cliente, etc. También tendré algunas cosas no materiales con las que estoy trabajando: una orden o una categoría. Una vez que tenga todos los "sustantivos" en el sistema, haré un modelo de dominio que muestre cómo se relacionan estos objetos entre sí: una orden tiene un cliente y múltiples SKU, muchos skus se agrupan en un producto, y así en.
Estos modelos de dominio se pueden representar como modelos de dominio UML, diagramas de clase y ERD de SQL.
Una vez que tengo los nombres del sistema resueltos, paso a los verbos, por ejemplo, las operaciones que atraviesa cada uno de estos elementos para enviar un pedido. Por lo general, estos mapas se asignan bastante bien para usar casos de mis requisitos funcionales. La forma más sencilla de expresarlos que he encontrado es la secuencia UML, la actividad o los diagramas de colaboración o los diagramas swimlane.
Es importante pensar en esto como un proceso iterativo; Haré un pequeño rincón del dominio, y luego trabajaré en las acciones, y luego regresaré. Idealmente, tendré tiempo para escribir código para probar cosas a medida que vaya avanzando; nunca querrá que el diseño vaya demasiado lejos de la aplicación. Este proceso generalmente es terrible si piensas que estás construyendo la arquitectura completa y final para todo; En realidad, todo lo que intenta hacer es establecer las bases básicas que el equipo compartirá en común a medida que avancen en el desarrollo. En general, estás creando un vocabulario compartido para que los miembros del equipo lo usen a medida que describen el sistema, sin establecer la ley sobre cómo se debe hacer.
Me encuentro teniendo problemas para pensar completamente en un sistema antes de codificarlo. Es demasiado fácil solo dar una mirada rápida a algunos componentes que más tarde te darás cuenta que son mucho más complicados de lo que creías.
Una solución es intentarlo realmente duro. Escribe UML en todas partes. Repasa todas las clases. Piensa cómo interactuará con tus otras clases. Esto es difícil de hacer
Lo que me gusta hacer es hacer una descripción general al principio. No me gusta UML, pero me gusta dibujar diagramas que transmitan el mensaje. Entonces comienzo a implementarlo. Incluso mientras escribo la estructura de clases con métodos vacíos, a menudo veo cosas que me perdí antes, así que actualizo mi diseño. Mientras estoy codificando, me daré cuenta de que tengo que hacer algo diferente, así que actualizaré mi diseño. Es un proceso iterativo . El concepto de "diseñar todo primero y luego implementarlo todo" se conoce como el modelo de cascada, y creo que otros han demostrado que es una mala forma de hacer software.
Me permito diferir: UML se puede usar para la arquitectura de aplicaciones, pero se usa más a menudo para la arquitectura técnica (marcos, diagramas de clase o secuencia, ...), porque aquí es donde esos diagramas se pueden mantener más fácilmente sincronizados con el desarrollo .
La arquitectura de aplicaciones se produce cuando se toman algunas especificaciones funcionales (que describen la naturaleza y los flujos de las operaciones sin hacer ninguna suposición acerca de una implementación futura) y se transforman en especificaciones técnicas.
Esas especificaciones representan las aplicaciones que necesita para implementar algunas necesidades comerciales y funcionales.
Entonces, si necesita procesar varias carteras financieras grandes (especificación funcional), puede determinar que necesita dividir esa especificación grande en:
- un despachador para asignar esos cálculos pesados a diferentes servidores
- un iniciador para asegurarse de que todos los servidores de cálculo estén en funcionamiento antes de comenzar a procesar esas carteras.
- una GUI para poder mostrar lo que está pasando.
- un componente "común" para desarrollar los algoritmos de cartera específicos, independientemente del resto de la arquitectura de la aplicación, para facilitar las pruebas unitarias, pero también algunas pruebas funcionales y de regresión.
Entonces, básicamente, pensar en la arquitectura de la aplicación es decidir qué "grupo de archivos" necesita desarrollar de forma coherente (no puede desarrollar en el mismo grupo de archivos un iniciador, una GUI, un despachador, ...: no podría evolucionar al mismo ritmo)
Cuando una arquitectura de aplicación está bien definida, cada uno de sus componentes suele ser un buen candidato para un componente de configuración , es decir, un grupo de archivos que puede ser versionado como un todo en un VCS (Sistema de control de versiones), lo que significa que todos sus archivos serán etiquetados juntos cada vez que necesite registrar una instantánea de esa aplicación (de nuevo, sería difícil etiquetar todo su sistema, cada una de sus aplicaciones no puede estar en un estado estable al mismo tiempo)
No estoy seguro de que algo pueda planificarse antes de la implementación. Tengo 10 años de experiencia, pero eso solo ha sido en 4 compañías (incluyendo 2 sitios en una compañía, que eran casi polos opuestos), y casi toda mi experiencia ha sido en términos de ver clúster colosal ****** ** s ocurrir. Estoy empezando a pensar que cosas como refactorizar es realmente la mejor manera de hacer las cosas, pero al mismo tiempo me doy cuenta de que mi experiencia es limitada, y que tal vez esté reaccionando a lo que he visto. Lo que realmente me gustaría saber es cómo obtener la mejor experiencia para poder llegar a conclusiones adecuadas, pero parece que no hay atajos y que implica mucho tiempo ver a las personas haciendo las cosas mal :(. Realmente me gustaría trabajar en una empresa donde las personas hacen las cosas bien (como lo demuestran las implementaciones exitosas de productos), para saber si soy un bastardo contrario, o si soy tan inteligente como creo Yo soy.
No soy lo suficientemente inteligente como para planear más que un poco. Cuando planifico con antelación, mis planes siempre saldrán mal, pero ahora he pasado n días con malos planes. Mi límite parece ser de unos 15 minutos en la pizarra.
Básicamente, hago el menor trabajo posible para descubrir si voy en la dirección correcta.
Miro mi diseño para preguntas críticas: cuando A hace de B a C, ¿será lo suficientemente rápido para D? Si no, necesitamos un diseño diferente. Cada una de estas preguntas puede responderse con un pico. Si los picos se ven bien, entonces tenemos el diseño y es hora de expandirlo.
Codigo en la dirección de obtener un valor real para el cliente lo antes posible, para que un cliente pueda decirme a dónde debería ir.
Como siempre hago las cosas mal, confío en la refactorización para ayudarme a hacerlas bien. La refacturación es arriesgada, así que tengo que escribir pruebas de unidades a medida que avanzo. Escribir las pruebas unitarias después de que el hecho es difícil debido al acoplamiento, entonces escribo mis pruebas primero. Mantenerse disciplinado sobre estas cosas es difícil, y un cerebro diferente ve las cosas de manera diferente, entonces me gustaría tener un amigo que codifique conmigo. Mi compañero de codificación tiene una nariz, así que me ducho regularmente.
Llamémoslo "Programación extrema".
Prueba Archimate.
Realmente creo que una primicia de escribir en papel o pizarra es realmente crucial. Luego, muévase a UML si lo desea, pero nada supera la flexibilidad de simplemente dibujarlo a mano al principio.
Si está desarrollando para .NET, Microsoft acaba de publicar (¡como libro electrónico gratuito!) La Application Architecture Guide 2.0b1 . Proporciona mucha información realmente buena sobre la planificación de su arquitectura antes de escribir cualquier código.
Si estuvieras desesperado, espero que puedas usar grandes cantidades de él para arquitecturas que no estén basadas en .NET.
UML es una notación. Es una manera de registrar su diseño, pero no (en mi opinión) de hacer un diseño. Si necesita escribir cosas, recomendaría UML, no porque sea el "mejor" sino porque es un estándar que otros probablemente ya saben leer, y es mejor que inventar su propio "estándar".
Creo que la mejor introducción a UML sigue siendo UML Distilled , de Martin Fowler, porque es concisa, proporciona una guía práctica sobre dónde usarla y deja en claro que no tiene que comprar toda la historia de UML / RUP para sé útil
Hacer diseño es difícil. Realmente no se puede capturar en una respuesta de . Desafortunadamente, mis habilidades de diseño, tal como son, han evolucionado a lo largo de los años y, por lo tanto, no tengo una fuente a la que pueda referirme.
Sin embargo, un modelo que he encontrado útil es el análisis de robustez (google for it, pero aquí hay una introducción). Si tienes tus casos de uso de lo que el sistema debería hacer, un modelo de dominio de lo que está involucrado, entonces he encontrado que el análisis de robustez es una herramienta útil para conectar los dos y determinar cuáles son los componentes clave del sistema. .
Pero el mejor consejo es leer ampliamente, pensar mucho y practicar. No es una habilidad puramente enseñable, tienes que hacerlo realmente.
Voy a prologar esto diciendo que hago principalmente desarrollo web donde gran parte de la arquitectura ya está decidida por adelantado (WebForms, ahora MVC) y la mayoría de mis proyectos son razonablemente pequeños, esfuerzos de una sola persona que toman menos de un año. También sé que tendré un ORM y DAL para manejar mi objeto comercial y la interacción de datos, respectivamente. Recientemente, he cambiado al uso de LINQ para esto, gran parte del "diseño" se convierte en el diseño y mapeo de la base de datos a través del diseñador de DBML.
Normalmente, trabajo de manera TDD (desarrollo impulsado por prueba). No paso demasiado tiempo trabajando en detalles arquitectónicos o de diseño. Reúno la interacción global del usuario con la aplicación a través de historias. Utilizo las historias para resolver el diseño de la interacción y descubrir los principales componentes de la aplicación. Hago un montón de pizarras blancas durante este proceso con el cliente, a veces capturando detalles con una cámara digital si parecen lo suficientemente importantes como para mantenerse en forma de diagrama. Principalmente mis historias son capturadas en forma de historia en una wiki. Eventualmente, las historias se organizan en lanzamientos e iteraciones.
En este momento, generalmente tengo una muy buena idea de la arquitectura. Si es complicado o hay bits inusuales, cosas que difieren de mis prácticas normales, o estoy trabajando con alguien más (no típico), voy a diagramar cosas (de nuevo en una pizarra). Lo mismo puede decirse de las interacciones complicadas: puedo diseñar el diseño de página y el flujo en una pizarra, manteniéndolo (o capturarlo a través de la cámara) hasta que haya terminado con esa sección. Una vez que tengo una idea general de hacia dónde voy y qué debe hacerse primero, comenzaré a escribir pruebas para las primeras historias. Usualmente, esto dice: "De acuerdo, para hacer eso necesitaré estas clases. Empezaré con esta y es necesario que haga esto". Luego empiezo alegremente a TDD y la arquitectura / diseño crece a partir de las necesidades de la aplicación.
Periódicamente, me gustaría escribir algunos trozos de código otra vez o pensar "esto realmente huele" y voy a refactorizar mi diseño para eliminar la duplicación o reemplazar las partes malolientes por algo más elegante. En su mayoría, me preocupa bajar la funcionalidad mientras sigo los buenos principios de diseño. Me parece que usar patrones conocidos y prestar atención a los buenos principios a medida que avanzas funciona bastante bien.
http://dn.codegear.com/article/31863
Uso UML, y encuentro esa guía bastante útil y fácil de leer. Avísame si necesitas algo diferente.