Cuando comienzo un nuevo proyecto, muchas veces inmediatamente empiezo a pensar en los detalles de la implementación. "¿Dónde voy a poner el DataBaseHandler? ¿Cómo debería usarlo? ¿Deberían las clases que quieran usarlo extenderse de alguna superclase abstracta? ¿Debería usar una interfaz? ¿Qué nivel de abstracción voy a usar en mi clase que contiene métodos para enviar solicitudes y analizar datos? "
Termino estancado durante mucho tiempo porque quiero codificar la extensibilidad y la reutilización. Pero siento que es casi imposible dejar de pensar en cómo implementarlo perfectamente.
Y luego, si trato de decir "¡atorníllelo, hágalo!", Golpeo una pared de ladrillos muy rápido porque mi código no está organizado, mezclo niveles de abstracciones, etc.
¿Cuáles son algunas técnicas / métodos que tiene para iniciar un nuevo proyecto y al mismo tiempo configurar una estructura lógica / modular que se adapte bien?
- - EDITAR - -
Bueno, este es el tipo de pregunta a la que es difícil aceptar una respuesta, pero quería obtener más comentarios, ver si hay algún consenso. TDD suena realmente genial y, francamente, he tenido la intención de ponerme al día con el uso de JUnit, etc. Al mismo tiempo, ¿qué piensan los fanáticos de TDD sobre el hecho de que un punto legítimo en relación con TDD para resolver mi problemas particulares, es que TDD realmente no parece abordar la cuestión del diseño. Claro, estoy de acuerdo en que TDD me ayudará a definir lo que quiero hacer y luego gradualmente puedo trabajar sobre cómo, pero hay muchos patrones / estructuras de diseño generales diferentes que podrían pasar por las pruebas unitarias. Eso es todo: prueba UNIDADES individuales. Supongo que estoy un poco confundido ... No sé. Talvez yo'
¡Gracias!
Respuestas:
Recomiendo usar Test-Driven-Development , lleva un tiempo acostumbrarse especialmente cuando se trabaja con un buen IDE como eclipse, pero las ventajas son excelentes.
Básicamente, lo que debe hacer es escribir las pruebas en su código antes de escribir el código en sí. Por lo tanto, se ve obligado a mirar su código desde el punto de vista de cómo se usará, lo que significa que sus interfaces evolucionan a medida que se implementan más escenarios.
Otra característica es que se implementa en trozos muy pequeños (se hacen más grandes cuanto más experiencia tenga en la técnica y en la programación), por lo que le obliga a centrarse en un problema muy pequeño y bien definido cada vez.
Y también desde que primero escribe una prueba y solo luego la implementa, tiene una prueba fallida frente a usted. Entonces, si usted es como la mayoría de los programadores, no se dejará llevar por un análisis loco porque pensará: "Necesito que esta prueba funcione".
Un breve ejemplo de Java:
Digamos que quiero desarrollar un programa que lea y escriba un mensaje desde un DB.
Así que empiezo con la primera acción bien definida, necesito un DB:
ok, entonces veo que necesito implementar la clase DbConnector.getDB para que devuelva la base de datos, hasta que esta prueba falle. Voy y hago eso ...
No agrego lo siguiente que quiero hacer, cargar el mensaje desde la base de datos:
Ahora he agregado otra pequeña característica a la base de datos que es buscar un mensaje, voy e implemento eso, una vez terminado, continúo con una función a la vez hasta llegar a algo como esto:
Puede parecer un ejemplo muy simple, pero esto también funciona para tareas más complejas. Sé que al principio lleva mucho tiempo, pero a medida que te acostumbras, ves que, de hecho, es mucho más eficiente. Para uno, evita la parálisis por análisis y para otro, obtiene un código mucho más robusto que generalmente tiene menos errores y pasa por menos iteraciones.
fuente
Esto me sucede a mí, así que me he acostumbrado a aceptar (y adoptar) una mentalidad de refactorización continua. Hago lo más simple que podría funcionar, luego lo limpio, lo organizo, lo desacopla, lo pruebo y sigo adelante.
Eso no quiere decir que no haya mucha planificación, pero sucede muy rápido y con mayor frecuencia como garabatos en la chatarra o en mi cabeza. En general, a veces llamo a este pequeño proceso micro iteraciones porque tardan de 5 a 20 minutos cada una y, por experiencia, se necesitan 2-3 para terminar lo que estoy trabajando (dependiendo de lo que estoy haciendo, obviamente).
Como nota al margen: he enseñado a varias personas en diferentes formas de escritura (informes, ensayos y redacción técnica en general) y esta es la misma forma en que hago que escriban cosas para superar el bloqueo del escritor. "Solo deja salir cualquier cosa sobre tu tema que se te ocurra en la página. Luego tendremos sentido y lo separaremos en párrafos y verificaremos el flujo. Si es necesario, incluso lo reescribiremos".
fuente
Algunas cosas que podrían funcionar:
fuente
Para muchas decisiones de diseño, puede ayudar hacer un "pico", que es un esfuerzo de investigación corto y de tiempo limitado en el que puede explorar algunas opciones de arquitectura u diseño codificando un prototipo desechable. Por ejemplo, podría explorar el uso de alguna biblioteca de código abierto o cómo organizará sus clases e interfaces. La clave es mantenerlo breve para que pueda probar otro enfoque si el primero no es satisfactorio y, con suerte, obtendrá el conocimiento suficiente en el ejercicio para tomar mejor las decisiones arquitectónicas o probar el concepto. El ejercicio en sí implica una codificación inmediata que ayuda a salir del "bloque de escritores" sin comprometerse necesariamente con el "git 'er done" demasiado pronto.
Después de eso, es beneficioso utilizar el enfoque TDD o BDD que Asaf mencionó para seguir adelante con la implementación del proyecto.
fuente
No lo necesitarás , así que no pienses demasiado al principio.
Invierta más tiempo para definir, comprender el objetivo y el problema.
La "extensibilidad y reutilización" es el resultado natural del ciclo de vida de los programas de software bien escritos.
fuente
Asumiré que estamos viendo un proyecto de tamaño mediano.
Empezaría yendo a la mesa de dibujo. Debe tener sus requisitos funcionales y no funcionales listos antes de hacer esto. Primero se te ocurrirá la arquitectura del software, es decir, mirar cualquier patrón arquitectónico que se adapte a tus requisitos
Una vez que decidas cómo se ve tu arquitectura, deberías pasar al diseño de bajo nivel, e mirar todas las entidades, clases y funcionalidades. . Aquí, nuevamente intentará e identificará los patrones de diseño que encajan. En el proceso, sabrá cuáles son sus clases base y las interfaces que necesitaría
. Luego puede construir el marco y ejecutar algunas pruebas rápidas para ver si esto satisface todos sus requisitos no funcionales
Luego iría con Test Driven Development como ha sugerido @Asaf.
Recuerde, a pesar de pasar un buen tiempo en diseño y arquitectura, siempre esté dispuesto a volver a visitar la arquitectura si surge la necesidad.
fuente
Creo que esta es una gran pregunta, y nada funcionará para todos. Creo que esa parálisis es un subproducto natural de ser cada vez más competente en su campo. Dicho esto, aquí hay algunas cosas que hago que ayudan, pero no resuelven el problema:
Ponga a un lado su proyecto original y trabaje en la versión fugia. Esta es la versión donde te dices a ti mismo: a. Se supone que el código no es bonito. De hecho, dite a ti mismo, no se permiten refactorizaciones y reformateos importantes. Deje que esté absolutamente desorganizado y libérese de los lazos de una buena codificación. si. Solo tiene que funcionar. do. Siempre me sorprende lo que aprendo sobre el espacio del problema cuando descarto todas las demás preocupaciones. También termino con pequeñas cositas que a menudo me ayudan a llegar al diseño correcto de una manera más ilustrada.
Reserve un período de tiempo decente en el que esté en el proyecto, simplemente sin una computadora. Intenta conceptualizar lo que realmente estás tratando de lograr y busca ese zen mágico que trascienda la locura de OO / Patrón de diseño.
fuente
Da una expresión concreta a tus pensamientos: escríbelos / escríbelos, dibuja o lo que sea. Esto lo ayudará a revisar sus pensamientos cuando sea necesario; te impedirá ir en círculos; te ayuda a pensar más claramente.
Cada vez que me veo yendo a ninguna parte y a todas partes pensando en algo, las escribo y me ayuda a pensar con claridad.
fuente
Por lo general, empiezo desde cero, creo el prototipo más simple posible y hago que algo funcione. Use el prototipo para realizar ingeniería inversa en los casos de prueba de ruta feliz, los casos de prueba para manejar las interfaces y luego piense en los contratos previos / posteriores para ayudar a construir la cobertura de prueba.
No se preocupe por la abstracción, la optimización o la verificación hasta que se comprenda completamente el problema.
fuente