traducir - desing o design
Diseñar mediante codificación, es incorrecto pero más fácil de visualizar (10)
Estoy seguro de que otros están de acuerdo, cuando el código llega al pavimento, es mucho más fácil pensar en todos los elementos que irán a su aplicación. Es decir, una vez que empiezas, piensas en lo que viene después porque has llegado al punto en el que tienes que diseñar otra mesa o clase.
Los inconvenientes de este enfoque son obvios y no necesitamos entrar en ello.
La pregunta es, para aquellos de nosotros que no podemos conceptualizar el diseño sin "verlo", ¿cómo pasar del diseño en el asiento de nuestros pantalones a una metodología más estructurada?
La única solución en la que puedo pensar son las especificaciones detalladas, que nos obligan a pensar exactamente cómo van a funcionar las cosas.
¿Es solo un caso de cómo la gente piensa de manera diferente, o hay algo más que ignoro?
BDUF flexible (Big Design Upfront). Hacer BDUF lo ayudará a detectar cualquier problema que deba tener en cuenta, una vez que acierte el código, aunque necesita ser flexible con su BDUF, algunas partes podrían estar equivocadas.
Usa ambos pero sigue aplicando el sentido común.
Bueno, no sé si esto es exactamente lo que estás preguntando, pero leer esta pregunta me recordó fuertemente a TDD (Desarrollo dirigido por prueba).
El objetivo de TDD es producir un código limpio y comprobable junto con un conjunto de pruebas de regresión automatizadas.
Me sorprende lo limpio que puede terminar el código cuando lo haces con TDD ... piensas en problemas, escribes pruebas para ello, implementas para que las pruebas pasen, luego refactorizas para asegurar que el código esté limpio y sea legible .
No creo que realmente NECESITES un diseño frontal con TDD, pero puede ser útil ... Estoy más que contigo en "diseño por codificación", pero al mismo tiempo puedes atrapar grandes fallas por delante de tiempo si lo piensas en una imagen más grande, aunque sea mínimamente.
Estás haciendo partes de Extreme Programming sin siquiera darte cuenta. De la wiki :
BigDesignUpFront se evita porque YouArentGonnaNeedIt. Sin embargo, una vez que se hace el SimplestThing, los programadores RefactorMercilessly, porque al final las cosas deben expresarse OnceAndOnlyOnce. Lea más acerca de SubsystemsInXp.
Como resultado, este tipo de programación no es necesariamente incorrecto. Se trata del enfoque que usa y de lo que puede hacer para impulsar mejor su propio éxito.
Estoy de acuerdo con la mayoría de lo que la gente dijo aquí, pero creo que se necesita una descripción más elaborada:
@public static: su afirmación es perfecta en cuanto a los problemas de diseño de avanzada ... Incluso si usted es una de esas personas increíblemente inteligentes, la crema de la crème de genios, no puede diseñar todo un sistema por adelantado . Podrías pensar que puedes, pero te estás engañando a ti mismo. La fuente de este problema es que, como dicen, "Dios está en los detalles". La idea de clavar un diseño apropiado desde el principio es pura arrogancia. Pero ... Eso no significa que no debamos dedicar tiempo a diseñar desde el principio.
Veamos cuál es nuestro propósito al "diseñar" un sistema:
Antes que nada, necesitamos un marco para pensar. ¿Alguna vez has intentado comenzar un nuevo proyecto? La parte más difícil es escribir la primera línea. ¿Por qué? Porque tienes un bloqueo de escritor, no tienes idea de a dónde te llevas. Por ejemplo, digamos que quieres escribir un juego de computadora, vamos a llamarlo "NotSoFarShout", que será el próximo shooter en primera persona super-genial que conquistará el mundo y te hará rico por toda la eternidad. Vamos a diseñar codificando ...
Comenzaremos con la función "principal" de nuestro programa:
void main(){
// Um, what the h*** should I put in "main"?!
}
Entonces, quizás el diseño por codificación no fue la decisión correcta. Probemos de otra manera:
Estamos planeando escribir un shooter en primera persona. ¿Qué es un tirador en primera persona de todos modos? OK, hablando en términos generales, es un mundo 3-D donde hay un personaje jugador, NPCs (personajes no jugadores, como personas malas, buenas personas, monstruos, gerbos, etc.), objetos (árboles, edificios, automóviles). El mundo se ve desde el punto de vista del personaje jugador. El personaje jugador puede obtener todo tipo de objetos como armas, municiones, paquetes de salud, etc. Hay un montón de otras cosas que describen un tirador en primera persona, pero vamos a seguir por un momento.
Sé que un tirador en primera persona tarda mucho tiempo en desarrollarse, definitivamente más de una semana o dos. ¿Cómo podría comenzar? Empiezo poco, y gradualmente escribo y diseño el sistema. Así que elijo una meta pequeña, alcanzable, a corto plazo que pueda entender conceptualmente y realmente pensar en cómo implementaré; por ejemplo, comenzaré con la visualización de un mundo 3-D. Sé que hay algunos buenos motores 3-D, investigaré un poco, elegiré uno y haré que se vea mi mundo, que actualmente está hecho de una sola esfera flotando en el vacío. Esto es algo que no debería tomar más de una semana o dos.
OK hecho. No me tomó dos semanas, en cambio me tomó tres, pero ahora tengo algo sobre lo que construir. Lo siguiente que podría decidir es construir una sola escena, estática por ahora, nada se mueve, ni AI, ni objetos con significado especial, personas, etc. Ahora viene la parte de diseño ... Cuando empiezo a pensar en representar una escena, diferente aspectos del mundo 3-D vendrían a mi mente:
- Mi escena muestra a dos personas de pie en el desierto, una de ellas está completamente quemada por el sol, la otra lleva un traje y un sombrero y sostiene una pistola en la mano.
- Pregunta 1: ¿Cómo describo el contenido de la escena? El motor 3-D necesita una representación específica para representar la escena. ¿Es intuitivo y fácil de usar? Si quiero cambiar la escena y mover el arma a la otra mano del personaje, ¿qué tan difícil es? ¿Qué pasa si quiero moverlo al otro personaje? ¿Qué sucede si quiero agregar una tercera persona? ¿Qué tan difícil es? ¿Qué pasa si quiero agregar 100 personas en lugares al azar en la escena, cada uno de ellos al azar con un arma y / o un sombrero?
- Pregunta 2: ¿Qué sucede si quiero que el color de la piel del personaje cambie con el tiempo? Por ejemplo, uno de los personajes está quemado por el sol. Si el otro se queda en esta escena del desierto el tiempo suficiente, ¿quiero que también se queme?
- Pregunta 3: El sol brilla en la escena, pero quiero que cambie con el tiempo; digamos que cada minuto es en tiempo real, es equivalente a 1 hora en el juego, así que quiero que el sol se mueva sobre el cielo y para la escena para convertirse gradualmente en noche, con o sin luna. Tal vez quiero que la luna atraviese sus fases a medida que pasan los días y las noches. ¿Cómo representaría eso?
La idea de este largo ejemplo es delinear estos problemas con el diseño:
Hay múltiples niveles de diseño. Al principio de la escritura de un producto / subsistema / módulo muy grande, generalmente solo puede realizar un diseño de muy alto nivel. Es decir, puede definir grandes entidades básicas como en nuestro ejemplo: motor 3-D, almacenamiento, redes, etc. Esto es importante para que pueda elegir dónde desea comenzar, dónde cree que estarán los mayores riesgos y similares. Tenga en cuenta que más adelante en el proceso, ese diseño inicial de alto nivel no solo se dividirá en detalles más pequeños y finos, sino que la mayoría de las veces descubrirá que tiene fallas y que cambiará para adaptarse a las necesidades del producto.
Una vez que haya elegido una pieza manejable en la que desee trabajar, es posible que tenga que crear un diseño detallado de esa pieza. Aquí es donde el diseño por codificación generalmente entra en juego. Sabes que quieres renderizar un mundo 3-D, pero no tienes idea de lo que se necesita. Entonces escribes un prototipo para renderizar una sola escena 3D. Luego creas una única escena estática. Luego miras lo que tienes y piensas: "OK, ¿y ahora qué necesito para hacer que esto sea útil para un juego de FPS? Necesitaré renderizar muchas escenas diferentes. De acuerdo, tomó mucho" describir "la escena actual en código, ¿cómo podría hacer que sea más fácil hacer variaciones en la escena actual? ¿Para crear una escena completamente nueva? ¿Cómo almacenaría descripciones de escena? ¿Archivos gráficos? ¿Archivos de sonido? ...". Esta es la manifestación de lo que alguien dijo antes (citando la forma de programación de XP): escribe lo que tiene que escribir en lugar de escribir un marco genérico y complejo por adelantado, pero una vez que tiene que escribir el mismo código con alguna variación ( representando una segunda escena, haciendo variaciones en la escena actual, etc.), es cuando generalizas y realzas el marco.
No tenga miedo de escribir prototipos desechables que resaltarán los diferentes aspectos que debe considerar en su diseño. De esa forma tienes una implementación concreta sobre la cual basar tu pensamiento.
Una vez más, citando a alguien aquí, ¡no congele su diseño! Es simplemente estúpido, si te das cuenta de que cometiste un error en tu diseño, refactorízalo para cambiarlo. Solo asegúrate de no cometer el error de tirar todo y empezar de cero. Hacer cambios incrementales a través de la refactorización generalmente funciona mucho mejor.
Por último, pero lo más importante, no estoy presentando nada especial o revolucionario aquí, todas estas ideas han sido delineadas por otras personas en la industria, mucho más inteligentes y con más experiencia que yo. Te recomiendo que leas un poco sobre "Programación extrema", Scrum y otras metodologías ágiles, así como libros generales sobre el tema como "El programador pragmático", "Código completo", "Refactorización", el libro "La pandilla de los cuatro" ( también conocido como "Patrones de diseño: elementos del software reutilizable orientado a objetos") ...
Espero que todo este texto haya sido útil :)
He tenido experiencia tanto desde el punto de vista del diseño completo desde el principio hasta el diseño mediante la codificación. Aquí está mi intento de describir mi punto de vista personal sobre el tema:
Los requisitos son la parte más importante y crucial del desarrollo. En el mundo de los negocios, este documento es lo que define su entregable, lo que legalmente necesita para darle al cliente y recibir el pago. En el caso de sus propios proyectos personales, aquí es donde saca una hoja de papel y anota el objetivo de su proyecto y luego determina sus necesidades a partir de ese objetivo.
Si tiene buenos requisitos y puede evitar cambiar los requisitos por capricho, aquí es donde puede recurrir al diseño de servilletas. Piensa en lo que quieres codificar y dibuja en un papel, esto te ayuda a pensar en varias posibilidades y te ayuda a escribir mejor código más tarde porque ya has pensado un poco. Si los requisitos cambian, intente trabajar en una nueva revisión, si eso tiene sentido.
Comience a escribir código, escriba pruebas y mantenga buenos comentarios en el código. Cuando empiece en otro módulo o sección de su aplicación, tómese un par de minutos para pensar en el diseño general de esa parte, ir y venir entre el diseño de su servilleta y su código. Acepte que tendrá que cambiar y modificar todo lo que pensaba que era perfecto antes de comenzar con otra parte de la aplicación y adoptar un enfoque iterativo para su desarrollo.
Si algo aprendí es que cualquier documentación de diseño está siempre desactualizada y terminas mirando el código de todos modos, mantener buenos comentarios vale tanto por eso. Los únicos documentos que creo que es importante mantener actualizados y sólidos son los requisitos y cualquier referencia API (si los tiene).
Lo estás haciendo bastante bien ahora porque seguir una especificación de diseño que se ha escrito desde cero es un campo minado de problemas. Puede diseñar desde el principio, pero debe estar preparado para terminar tirando o rediseñando la mayor parte del diseño a medida que codifica. En mi opinión, esto es independientemente si lo estás haciendo TDD o no, tienes que diseñar codificando para verificar el diseño inicial.
Recuerde niños: congelar una especificación de diseño antes de codificar es estúpido .
No digo que se suponga que no debes diseñar de antemano como pensar antes de que el código ayude en algunas situaciones. Debería poder equilibrar la cuota de codificación vs. diseño usted mismo. Intuitivamente, si sabes mucho cómo debería ser el código, planifica y luego codifica. Si no lo hace, hackearlo y luego rediseñarlo (es decir, refactorizar).
No estoy de acuerdo con la idea de que el diseño mientras se codifica es incorrecto.
De hecho, soy un gran defensor de la idea de que la codificación es diseño . La programación no es un trabajo mecánico, sino creativo, donde debe tomar decisiones entre alternativas de implementación todo el tiempo.
No estoy en contra de las especificaciones o el diseño arquitectónico, pero ciertamente el trabajo de diseño no termina cuando el documento de arquitectura está terminado.
Si no ha consultado este libro Refactoring de Martin Fowler, debería hacerlo. El crimen no es tanto el desarrollo / prototipado rápido, es saber cómo poner ese último pedazo en algo más fácil de mantener en un plazo bastante corto. Sí, descubrirá nuevos objetos sobre la marcha, ahora dedique un poco de tiempo a limpiar y luego continuar. A menudo terminas con un producto mejor que si trataras de diseñar la mayor parte de la solución de antemano.
Solo algunos puntos.
En cada generación ... encontrará gente ansiosa por adoptar la última metodología y usarla. Soy un probador temprano, lo que significa que generalmente pruebo cada cosa nueva que sale, pero ...
Acerca de TDD, realmente, ¿por qué diablos debería escribir una prueba antes de escribir el código? El propósito de una prueba es ... bueno, para probar algo, no codifica una prueba para algo que tal vez no necesite una prueba codificada. Tal vez si lo haces se te acabará el tiempo (hay programas de proyectos que conoces), tal vez la prueba en sí sea tan compleja que necesitarás verificarla para demostrar que es correcta. Trabajamos para vivir, no lo contrario, y codificamos algunas pruebas para probar algunas partes del código, no al revés. Además, recuerde que esto es negocio, tiene que haber una tasa de retorno, la ganancia de hacer algo perfecto pero no cobrar es cero, no importa cuán bueno sea.
Sobre el diseño por codificación. En serio, esto funciona para todos los aspectos de la vida, piensa antes de hacerlo (y piensa antes de hablar ). ¿Qué hay de malo en pensar en el diseño antes de hacerlo? Consiga un bolígrafo y un trozo de papel y haga un boceto de su diseño, planifique algunas clases, intente imaginarse LO QUE HARÁ primero, las PIEZAS del sistema en segundo lugar y CÓMO SE RELACIONARÁ con el último. Entonces puedes comenzar a pensar cómo exactamente se va a implementar. ¿Qué sentido tiene comenzar a codificar sin pensar en lo que estás haciendo?
Si no puede pensar en el diseño sobre un papel, si solo puede pensar en el código que va a escribir, lamente que no sea la persona adecuada para diseñar el sistema, pero no comience a codificar antes de tener el diseño . El código es una entidad viviente, y también lo es el diseño, lo que significa que se supone que evolucionan y se adaptan durante el proceso de desarrollo, pero se supone que no deben tomarse a la ligera o ser apresurados.
Editar: Sé que soy duro para TDD, lo siento y estoy dispuesto a escuchar experiencias pero todavía estoy buscando encontrar un uso de TDD en un proyecto grande (digamos más de 7000 horas de trabajo) que ha trabajado usando TDD. Quiero decir, proyecto real con fechas precisas y dinero involucrado.
Test Driven Development (TDD) es una técnica que inmediatamente viene a la mente para apoyar su práctica actual de "Design by Coding". Implementado adecuadamente, esto le permitirá refactorizar su código con confianza y eso es esencial si está desarrollando su diseño gradualmente.
Por cierto, TDD funciona muy bien con un enfoque de estilo de Scrum para la gestión de proyectos, que también suele ser ligero en la documentación.
Uno de los mantras ágiles es lanzar temprano y soltar a menudo. Parece que ya está haciendo algo similar, solo necesita colocar las estructuras en su lugar para que pueda responder a los cambios en el diseño sin el temor de romper su código.