¿Cómo diseñas proyectos orientados a objetos? [cerrado]

231

Estoy trabajando en un gran proyecto (para mí) que tendrá muchas clases y tendrá que ser extensible, pero no estoy seguro de cómo planificar mi programa y cómo las clases deben interactuar.

Tomé un curso de OOD unos semestres atrás y aprendí mucho de él; como escribir UML y traducir documentos de requisitos en objetos y clases. También aprendimos diagramas de secuencia, pero de alguna manera me perdí la conferencia o algo así, realmente no se quedaron conmigo.

Con proyectos anteriores que he intentado usar métodos que aprendí en el curso, pero usualmente termino con un código que tan pronto como puedo decir "sí, eso se parece a lo que tenía en mente", no tengo ganas de hurgar en la basura para agregar nuevas características.

Tengo una copia del Código completo de Steve McConnell que continuamente escucho es increíble, aquí y en otros lugares. Leí el capítulo sobre diseño y no parecía salir con la información que estaba buscando. Sé que dice que no es un proceso de corte y secado, que se basa principalmente en la heurística, pero parece que no puedo tomar toda su información y aplicarla a mis proyectos.

Entonces, ¿ qué cosas hace durante la fase de diseño de alto nivel (antes de comenzar a programar) para determinar cuáles son las clases que necesita (especialmente las que no están basadas en ningún "objeto del mundo real") y cómo interactuarán entre sí ?

Específicamente, me interesan los métodos que utiliza. ¿Cuál es el proceso que sigue que generalmente produce un diseño bueno y limpio que representará de cerca el producto final?

Victor
fuente
2
Pensé que Code Complete fue bastante útil en este tema, particularmente los capítulos 5.3 y 5.4 (que tienen algunas sugerencias más concretas), y todo el capítulo 6. Sin embargo, en realidad no he hecho ningún diseño de código para un proyecto grande.
Paul D. Waite
1
Puedo recomendar tomar un curso sobre diseño orientado a objetos en Java. Hay uno excelente publicado en UDEMY udemy.com/mastering-object-oriented-design-in-java/… . Creo que eso ciertamente puede ayudarte. Otro gran recurso es probar el problema orientado a objetos ATM. Puedes googlear eso.
Horse Voice
Recomendaría a todos que vuelvan a esta pregunta cuando realmente estén haciendo el diseño. Hay mucho contenido aquí. De esta manera, puede refrescar su memoria mientras realiza el diseño real.
Kevin Wheeler

Respuestas:

199

Los pasos que utilizo para el diseño inicial (llegar a un diagrama de clase) son:

  1. Recopilación de requisitos. Hable con el cliente y factorice los casos de uso para definir qué funcionalidad debe tener el software.

  2. Componga una narración de los casos de uso individual.

  3. Repase la narrativa y resalte los sustantivos (persona, lugar, cosa), como clases de candidatos y verbos (acciones), como métodos / comportamientos.

  4. Deseche nombres duplicados y factorice la funcionalidad común.

  5. Crea un diagrama de clase. Si usted es un desarrollador de Java, NetBeans 6.7 de Sun tiene un módulo UML que permite la creación de diagramas, así como la ingeniería de ida y vuelta y es GRATIS. Eclipse (un IDE Java de código abierto), también tiene un marco de modelado, pero no tengo experiencia con él. También puede probar ArgoUML, una herramienta de código abierto.

  6. Aplique los principios de OOD para organizar sus clases (factorice la funcionalidad común, cree jerarquías, etc.)

Scott Davies
fuente
66
De hecho, esta es una técnica útil, especialmente cuando no tiene un control real sobre el dominio del problema. Sin embargo, rara vez produce una arquitectura óptima.
NomeN
1
Puedo recomendar tomar un curso sobre diseño orientado a objetos en Java. Hay uno excelente publicado en UDEMY udemy.com/mastering-object-oriented-design-in-java/…. Creo que eso ciertamente puede ayudarte. Otro gran recurso es probar el problema orientado a objetos ATM. Puedes googlear eso.
Horse Voice
1
¿Dónde aprendes esto? ¿Podría por favor proporcionar la fuente de eso?
Kanagavelu Sugumar
68

Además de lo que Scott Davies tenía que decir:

  1. Asegúrese de saber de qué se trata su programa antes de comenzar. Cual es tu programa ¿Qué no hará? ¿Qué problema está tratando de resolver?

  2. Su primer conjunto de casos de uso no debería ser una lista exhaustiva de todo lo que el programa eventualmente hará. Comience con el conjunto más pequeño de casos de uso que pueda encontrar y que aún capture la esencia de para qué es su programa. Para este sitio web, por ejemplo, los casos de uso principales pueden ser iniciar sesión , hacer una pregunta , responder una pregunta y ver preguntas y respuestas . Nada sobre reputación, votación o el wiki de la comunidad, solo la esencia cruda de lo que estás buscando.

  3. A medida que piense en posibles clases, no piense en ellas solo en términos del nombre que representan, sino de las responsabilidades que tienen. He encontrado que esta es la mayor ayuda para descubrir cómo se relacionan las clases entre sí durante la ejecución del programa. Es fácil encontrar relaciones como "un perro es un animal" o "un cachorro tiene una madre". Por lo general, es más difícil descubrir relaciones que describan interacciones en tiempo de ejecución entre objetos. Los algoritmos de su programa son al menos tan importantes como sus objetos, y son mucho más fáciles de diseñar si ha explicado cuál es el trabajo de cada clase.

  4. Una vez que tenga ese conjunto mínimo de casos de uso y objetos, comience a codificar. Obtenga algo que realmente se ejecute lo antes posible, a pesar de que no hace mucho y probablemente parece una mierda. Es un punto de partida y te obligará a responder preguntas que podrías pasar por alto en papel.

  5. Ahora regrese y elija más casos de uso, escriba cómo funcionarán, modifique su modelo de clase y escriba más código. Al igual que su primer corte, tome la menor cantidad posible a la vez que aún agrega algo significativo. Enjuague y repita.

Solo mis dos centavos. Ojalá sea útil.

Darryl
fuente
19

Cuando tuve la oportunidad, normalmente uso lo que llamo la "regla de las tres iteraciones".

En la primera iteración (o inicio), ideo el diseño general de la aplicación de acuerdo con los objetos del modelo, los algoritmos y lo esperado ( realmente esperado, quizás noesperado) direcciones futuras. No escribo documentos de diseño, pero si tengo que coordinar a varias personas, por supuesto, se necesita un bosquejo del procedimiento, junto con un análisis de las dependencias y una estimación aproximada del tiempo necesario. Intenta mantener esta fase al mínimo si, como yo, prefieres un método más ágil. Hay casos en los que se necesita una fuerte fase de diseño, en particular cuando todo es conocido y verdadero acerca de la lógica de su programa, y ​​si planea tener muchas interacciones entre las características de su código. En este caso, los casos de uso o las historias de los usuarios son una buena idea de alto nivel, en particular para las aplicaciones GUI. Para aplicaciones de línea de comandos, y en particular bibliotecas, intente escribir "historias de programas" en las que codifique contra la biblioteca que tiene que desarrollar y compruebe cómo se ve.

Después de esta primera iteración, comprenderá mejor cómo interactúan las cosas, sacó los detalles y los puntos difíciles, resolvió los problemas con un parche de cinta adhesiva. Está listo para usar esta experiencia para mejorar, limpiar, pulir, dividir lo que era demasiado grande, fusionar lo que estaba demasiado fragmentado, definir y usar patrones de diseño, analizar cuellos de botella de rendimiento y problemas de seguridad no triviales. En general, todos estos cambios tendrán un gran impacto en las pruebas unitarias que escribió, pero no en las pruebas funcionales.

Cuando complete esta segunda iteración, tendrá una pequeña joya, bien probada, bien documentada y bien diseñada. Ahora tiene la experiencia y el código para hacer la tercera iteración, extender. Agregará nuevas funciones y casos de uso para mejorar su aplicación. Encontrará puntos difíciles y eventualmente ingresará a una cuarta iteración que es análoga a la segunda. Enjuague y repita.

Este es mi enfoque general para el diseño de software. Es similar al diseño en espiral, con iteraciones cortas de tres meses y elementos de desarrollo ágil, que le permite aprender los problemas y conocer su software y su campo de aplicación. Por supuesto, es una cuestión de escalabilidad, por lo que si la aplicación es tan grande que involucra a cientos de desarrolladores, las cosas son un poco más complejas que esto, pero al final supongo que la idea es siempre la misma, divide et impera .

En resumen:

  1. En la iteración uno, lo pruebas y aprendes
  2. En la segunda iteración, usted limpia su producto y lo prepara para el futuro.
  3. En la iteración tres, agrega nuevas funciones y aprende más
  4. ir a 2
Stefano Borini
fuente
16

La fuente más interesante que conozco sobre esto es la Parte D de Construcción de software orientada a objetos, 2ª edición, de Bertrand Meyer.

Parte D: Metodología orientada a objetos: aplicando bien el método

19: Sobre metodología, 20: Patrón de diseño: sistemas interactivos de paneles múltiples, 21: Estudio de caso de herencia: "deshacer" en un sistema interactivo, 22: Cómo encontrar las clases , 23: Principios del diseño de clase, 24: Usar bien la herencia , 25: Técnicas útiles, 26: Un sentido del estilo, 27: Análisis orientado a objetos, 28: El proceso de construcción del software, 29: Enseñar el método

Curiosamente, el capítulo 22. Cómo encontrar las clases está disponible en línea.

Daniel Daranas
fuente
12

A menudo se repite pero es completamente cierto: comprenda sus datos.

Para OOP, sus clases deben describir piezas destacadas de información y cómo interactúan.

Si tiene un modelo mental que describe bien el comportamiento y la vida útil de los datos, tendrá un paseo fácil para diseñar sus clases.

Esto es simplemente una extensión de: Sepa exactamente lo que está tratando de hacer.

Dave Gamble
fuente
12
El comportamiento del objeto es más importante que los datos. Este es un resultado directo de la encapsulación: el corazón de la programación orientada a objetos. La exposición de datos (de lenguajes como C y Pascal) conduce a sistemas que son difíciles de mantener (mejorar y depurar) simplemente porque nunca se sabe qué otro lugar del sistema cambia los datos. OOP no se trata de datos; OOP se trata de comportamiento. Es una distinción importante.
Dave Jarvis el
Es una distinción importante, pero no significa que el comportamiento sea más importante que los datos.
Johnny
Para OOD, generalmente comienzo desde el diseño del Modelo después de aclarar los requisitos, lo que me da una idea básica de cómo deben organizarse las entidades y cómo la relación entre ellas. Al mismo tiempo, tengo una idea básica sobre las operaciones que podrían ocurrir en cada entidad. Después de una imagen borrador sobre modelos, podemos revisar los requisitos y verificar si nos falta algo. Y luego será más fácil volver al nivel de clase y al nivel de controlador.
Joshua
10

Intente utilizar el desarrollo impulsado por el comportamiento. Será difícil romper tus viejos hábitos, pero descubrí que BDD es realmente tu mejor opción cuando se trata de desarrollar en el mundo real.

http://behaviour-driven.org/

Eric el rojo
fuente
1
+1 El uso del desarrollo impulsado por prueba / comportamiento / dominio le permite crear clases a medida que avanza para evitar la problemática metodología de cascada de diseño inicial.
Halvard
8

El problema con los proyectos grandes es que no puede supervisar todas las interacciones entre los componentes. Por lo tanto, es importante reducir la complejidad del proyecto. Los diagramas de clase y secuencia son demasiado detallados para esta fase de diseño.

Primero trate de pensar desde un nivel de abstracción más alto. Piense en los componentes principales y sus responsabilidades (su interfaz con otros componentes), observe algunos patrones arquitectónicos en busca de inspiración (no, no patrones de diseño, ¡estos son niveles demasiado bajos! MVC y Multi-Tier son ejemplos de patrones arquitectónicos). Para proyectos razonablemente grandes, dicha vista debería tener entre 3 y 5 componentes.

Solo entonces te acercas a un determinado componente e intentas diseñarlo. Ahora estamos a nivel de patrones de diseño y diagramas de clases. Intente enfocarse en esta parte del proyecto, si considera que necesita agregar una responsabilidad a uno de los otros componentes, simplemente agréguelo a su documentación / lista de tareas pendientes. No pierda el tiempo pensando en las implicaciones que en este momento cambian demasiado rápido, revise cuando el diseño sea más sólido.

No es necesario diseñar completamente cada componente en este punto, aunque probablemente sea aconsejable tener un código que implemente la interfaz de componentes no implementados y genere respuestas simples pero útiles. De esta manera, puede comenzar a desarrollar (y diseñar) un componente a la vez y probarlo en un grado razonable.

Por supuesto, cuando se completan nuevos componentes, debe probar cómo (y si) se integran entre sí antes de continuar.

En resumen: ¡toma el principio de ocultación de información y OO y sube a otro nivel!


PD: Dibuja mucho mientras diseñas, ¡es como la arquitectura real!

PPS: trate de abordar el asunto desde diferentes ángulos, piense fuera de la caja (aunque la caja podría ser el camino a seguir), discutir con sus compañeros puede ser muy útil para esto ... y tiene algo de qué hablar durante el almuerzo.

revs NomeN
fuente
7

La técnica que he utilizado en proyectos reales con un éxito razonable es el Diseño impulsado por la responsabilidad, inspirado en el libro de Wirfs-Brock.

Comience con las historias de usuarios de nivel superior, y con colegas, en una pizarra, dibuje las interacciones de alto nivel que implican. Esto le da la primera idea de cuáles son los módulos grandes; y una o dos iteraciones de juego de cartas CRC de alto nivel, debería haber estabilizado una lista de componentes principales, qué hacen y cómo interactúan.

Luego, si alguna de las responsabilidades es grande o compleja, refine esos módulos hasta que tenga cosas que sean lo suficientemente pequeñas y simples como para ser objetos, reproduciendo las interacciones dentro del módulo para cada una de las operaciones principales identificadas por las interacciones de nivel superior .

Saber cuándo parar es una cuestión de juicio (que solo viene con la experiencia).

Steve Gilham
fuente
+1 para la pizarra, algo sobresaliente: DI resuelve el 80% de los problemas frente a la pizarra, solo mirándolo y pensando '¿cuál sería el mejor?'
usoban
7

Patrones de diseño

Patrones de diseño creacional

Singleton: asegúrese de que solo se crea una instancia de una clase y proporcione un punto de acceso global al objeto.

Factory (versión simplificada del método Factory): crea objetos sin exponer la lógica de creación de instancias al cliente y hace referencia al objeto recién creado a través de una interfaz común.

Método de fábrica: define una interfaz para crear objetos, pero permite que las subclases decidan qué clase instanciar y se refiere al objeto recién creado a través de una interfaz común.

Abstract Factory: ofrece la interfaz para crear una familia de objetos relacionados, sin especificar explícitamente sus clases.

Generador: define una instancia para crear un objeto, pero permite que las subclases decidan qué clase instanciar y permite un control más preciso sobre el proceso de construcción.

Prototipo: especifique los tipos de objetos para crear utilizando una instancia prototípica y cree nuevos objetos copiando este prototipo.

Patrones de diseño conductual

Cadena de responsabilidad: evita vincular el remitente de una solicitud a su receptor, lo que le da a otros objetos la posibilidad de manejar la solicitud también. - Los objetos se convierten en partes de una cadena y la solicitud se envía de un objeto a otro a través de la cadena hasta que uno de los objetos lo maneje.

Comando: encapsula una solicitud en un objeto, permite la parametrización de clientes con diferentes solicitudes y permite guardar las solicitudes en una cola.

Intérprete: dado un idioma, defina una representación para su gramática junto con un intérprete que use la representación para interpretar oraciones en el idioma / Asigne un dominio a un idioma, el lenguaje a una gramática y la gramática a un diseño jerárquico orientado a objetos.

Iterador: proporciona una forma de acceder a los elementos de un objeto agregado de forma secuencial sin exponer su representación subyacente.

Mediador: defina un objeto que encapsule cómo interactúa un conjunto de objetos. El mediador promueve el acoplamiento suelto al evitar que los objetos se refieran entre sí explícitamente y le permite variar su interacción de forma independiente.

Observador: defina una dependencia de uno a muchos entre objetos para que cuando un objeto cambie de estado, todos sus dependientes sean notificados y actualizados automáticamente.

Estrategia: defina una familia de algoritmos, encapsule cada uno y hágalos intercambiables. La estrategia permite que el algoritmo varíe independientemente de los clientes que lo usan.

Método de plantilla: defina el esqueleto de un algoritmo en una operación, aplazando algunos pasos a subclases / El Método de plantilla permite a las subclases redefinir ciertos pasos de un algoritmo sin permitir que cambien la estructura del algoritmo.

Visitante: representa una operación que se realizará en los elementos de una estructura de objeto / Visitante le permite definir una nueva operación sin cambiar las clases de los elementos en los que opera.

Objeto nulo: proporcione un objeto como sustituto por la falta de un objeto de un tipo dado. / El patrón de objeto nulo proporciona un comportamiento inteligente para no hacer nada, ocultando los detalles de sus colaboradores.

Patrones de diseño estructural

Adaptador: convierta la interfaz de una clase en otra interfaz que los clientes esperan. / Adapter permite que las clases trabajen juntas, que de otro modo no podrían debido a interfaces incompatibles.

Puente - Componga objetos en estructuras de árbol para representar jerarquías de parte completa. / Composite permite a los clientes tratar objetos individuales y composiciones de objetos de manera uniforme.

Compuesto: componga objetos en estructuras de árbol para representar jerarquías de parte completa. / Composite permite a los clientes tratar objetos individuales y composiciones de objetos de manera uniforme.

Decorador: agregue responsabilidades adicionales dinámicamente a un objeto.

Flyweight: utilice el uso compartido para admitir una gran cantidad de objetos que tienen parte de su estado interno en común donde la otra parte del estado puede variar.

Memento: captura el estado interno de un objeto sin violar la encapsulación y, por lo tanto, proporciona un medio para restaurar el objeto al estado inicial cuando sea necesario.

Proxy: proporcione un "Marcador de posición" para que un objeto controle referencias a él.

Sauron
fuente
2
Los patrones son útiles para algunas personas. Creo que se necesita una experiencia considerable para ver los patrones en los requisitos. Y probablemente necesites documentarlos. Me inclino a pensar que los patrones no son más que bibliotecas de componentes abstractos.
CyberFonic el
5

Le recomendaría que use BlueJ y también ActiveWriter para aprender y también para desarrollar una buena comprensión de los objetos. El libro recomendado es también un buen recurso.

De Wikipedia :

texto alternativo

BlueJ es un entorno de desarrollo integrado para el lenguaje de programación Java, desarrollado principalmente con fines educativos, pero también adecuado para el desarrollo de software a pequeña escala.

Además, utiliza UML y para mí fue un buen recurso para comprender varias cosas sobre el modelado de objetos.

texto alternativo http://www.ryanknu.com/ryan/bluej.png

ActiveWriter es una herramienta para modelar entidades y relaciones, también genera código y es fácil realizar cambios. Le ahorrará tiempo y para un desarrollo ágil es muy adecuado.

texto alternativo
(fuente: altinoren.com )

Nelson Miranda
fuente
1
He usado J azul ... es definitivamente útil, pero ¿cómo me ayuda a diseñar clases y sus relaciones?
Victor
1
Creo que me dejó claro ver la imagen completa sobre cómo identificar las clases y cómo relacionarlas visualmente, en mis primeros pasos experimenté cómo era la representación de código de los objetos y cómo entender para pensar en los objetos. Recuerdo cuando dediqué tiempo a descubrir "es un" y "tiene un" y el UML fue una ayuda excelente. Desde entonces, utilizo estas herramientas visuales para diseñar mis objetos y cuando descubrí ActiveWriter, estaba muy contento porque BlueJ no tiene generación de código y esta herramienta sí, solo para reforzar mi argumento, creo que visualmente tiene un enfoque más amplio para una solución.
Nelson Miranda
4

En primer lugar, el diseño debe venir de tu alma. Debe sentirlo con cada fibra. Por lo general, camino por dos o tres meses antes de comenzar a hacer cualquier cosa, solo caminando por las calles (realmente). Y pensando Caminar es una buena meditación, ya sabes. Entonces te permite concentrarte bien.

En segundo lugar, use OOP y clases solo donde exista una jerarquía de objetos naturales. No lo atornille a eso artificialmente. Si no existe una jerarquía estricta (como en la mayoría de las aplicaciones comerciales), elija procedimientos / funciones o, al menos, use objetos solo como contenedores de datos con accesos aislados.

Y el último: intenta leer esto: El algoritmo del pensamiento creativo

Thevs
fuente
4

Solo citando http://www.fysh.org/~katie/computing/methodologies.txt

Y en el núcleo de RUP hay un área pequeña donde tienes que usar talentos de diseño OO ... si no los tienes, es como tener una metodología para correr los 100m.

"Paso 1: escribe sobre correr muy rápido. Paso 2: ve y dibuja un plano de la pista. Paso 3: ve y compra shorts muy ajustados de lycra. Paso 4: corre muy, muy, muy rápido. Paso 5: cruza primero la línea "

Es el paso 4 el más difícil. Pero si pone mucho énfasis en 1,2,3 y 5, es posible que nadie se dé cuenta y entonces probablemente podría ganar mucho dinero vendiendo la metodología a los atletas que piensan que hay un "secreto" para estar a 100 metros. corredor sobre

martín
fuente
4

Hiciste una pregunta que muchos autores usan para escribir un libro. Hay varias metodologías y debe elegir una que le parezca "más bonita".
Puedo recomendar el libro "Domain Driven Design" de Eric Evans. Además, consulte el sitio dddcommunity.org .

zendar
fuente
3

Creo que la respuesta aquí debería ser muy diferente dependiendo de la experiencia en el mundo real del tipo que pregunta.

Si tiene solo uno o dos años de experiencia laboral, debe ir al punto que es: ¿cómo llegar al punto en el que realmente conoce sus datos y comprende exactamente lo que está tratando de hacer?

Sí, si ha estado trabajando en el mundo real más de 5 años, entonces elegiría entre cualquiera de los muchos modelos o técnicas de procesos de desarrollo de software.

Pero no obtienes experiencia leyendo solo libros. Debes aprender trabajando en un buen grupo bajo un buen liderazgo.

Si eso no es posible, entonces debes hacerlo solo. Comience iterando codificando un fragmento de código probablemente muy desagradable, aprendiendo sus errores, descartándolo todo, codificando uno mejor, etc.

Aprenderá mucho sobre su base de código. Las herramientas son herramientas, no te enseñarán nada.

revs IlDan
fuente
3

Si tiene experiencia en el dominio del proyecto en el que va a trabajar, por ejemplo, en banca. Es fácil estructurar sus objetos y sabe cómo esas mejoras se producen cada dos días.

Si no tiene esa experiencia, trabaje con alguien que tenga esa experiencia y convierta esas ideas en detalles técnicos.

Si está confundido acerca de cómo estructurar el diseño de su proyecto. Siga ciegamente el libro "programador pragmático". Estaba en la misma situación antes, intente leer un capítulo de ese libro. verá la diferencia, cambiará su forma de pensar como desarrollador de software.

Enlace roto
fuente
2
  1. Estudiar y dominar los patrones de diseño.
  2. A continuación, aprenda sobre el diseño impulsado por dominio
  3. Después de eso, aprenda la recopilación de requisitos.

Tomé un curso de OOD unos semestres atrás y aprendí mucho de él; como escribir UML y traducir documentos de requisitos en objetos y clases. También aprendimos diagramas de secuencia, pero de alguna manera me perdí la conferencia o algo así, realmente no se quedaron conmigo.

  1. Conoces el paso 3. Necesitas dominarlo. Quiero decir, a través de mucha práctica para que se convierta en tu segunda naturaleza. Esto se debe a que el método que aprende es simplemente contrario a lo que solíamos tener. Entonces necesitas dominarlo realmente. De lo contrario, siempre volverá a su forma original de hacer las cosas. Esto es de alguna manera como Test Driven Process, donde muchos desarrolladores de Java lo abandonan después de algunos intentos. A menos que lo dominen por completo, de lo contrario es solo una carga para ellos

  2. Escriba casos de uso, especialmente para cursos alternativos. El curso alternativo ocupa más del 50% de nuestro tiempo de desarrollo. Normalmente, cuando su PM le asigna una tarea, por ejemplo, crear un sistema de inicio de sesión, pensará que es sencillo, puede tomar 1 día para terminarlo. Pero nunca tiene en cuenta que debe tener en cuenta: 1. qué sucede si el usuario ingresa una contraseña incorrecta, 2. qué sucede si el usuario ingresa una contraseña incorrecta 3 veces, 3. qué sucede si el usuario no escribe el nombre de usuario, etc. Debe enumerarlos y mostrarlos a su PM, pedirle que reprograme la fecha límite.

janetsmith
fuente
2

Me temo que esta no es una respuesta que a la gente le gusta escuchar . De todos modos, déjenme expresar mi opinión.

OOP debe ser visto como uno de los paradigmas, no como el paradigma superior. OOP es bueno para resolver cierto tipo de problemas, como desarrollar una biblioteca GUI. También encaja en el estilo de desarrollo de software que suelen seguir las grandes compañías de software: un equipo de élite de diseñadores o arquitectos establece el diseño del software en diagramas UML u otro medio similar y un equipo de desarrolladores menos ilustradotraduce ese diseño en código fuente. OOP ofrece pocos beneficios si está trabajando solo o con un pequeño equipo de programadores altamente talentosos. Entonces, es mejor usar un lenguaje que admita múltiples paradigmas y lo ayudará a crear un prototipo rápidamente. Python, Ruby, Lisp / Scheme, etc.son buenas opciones. El prototipo es tu diseño. Entonces mejoras en eso. Use el paradigma que sea mejor para resolver el problema en cuestión. Si es necesario, optimice los puntos calientes con extensiones escritas en C o en algún otro lenguaje de sistemas. Al usar uno de estos idiomas, también obtienes extensibilidadde forma gratuita, no solo a nivel de programador sino también a nivel de usuario. Los lenguajes como Lisp pueden generar y ejecutar código dinámicamente, lo que significa que sus usuarios pueden extender la aplicación escribiendo pequeños fragmentos de código, en el idioma en que el software está codificado. O si elige escribir el programa en C o C ++, considere incorporar un intérprete para un lenguaje pequeño como Lua. Exponga funcionalidades como complementos escritos en ese idioma.

Creo que, la mayoría de las veces, OOP y OOD crean software que son víctimas de un diseño excesivo.

Para resumir, mi forma preferida de escribir software es:

  1. Usa un lenguaje dinámico.
  2. Escriba el diseño (prototipo) en ese lenguaje en sí.
  3. Si es necesario, optimice ciertas áreas usando C / C ++.
  4. Proporcione extensibilidad por medio del intérprete del lenguaje de implementación en sí.

La última característica permite que el software se adapte fácilmente a los requisitos específicos del usuario (¡incluido yo mismo!).

Vijay Mathew
fuente
Esto no es un consejo sobre cómo diseñar
NomeN
2
Yo uso un enfoque similar. Para evitar sentirse abrumado por la complejidad, comience con una vista en helicóptero. Me gusta un boceto con 8-20 funciones. Si empiezo a obtener más, miro cómo particionar en subsistemas. Una vez que tenga esa vista de alto nivel, descompondré cada función en 8-20 subfunciones, etc. Al observar qué manipulan esas funciones, obtengo las clases de nivel superior. Es entonces cuando comienzo a diseñar el sistema esquelético en Python, también conocido como pseudocódigo ejecutable. Eso junto con los bloques de comentarios es mi 'especificación ejecutable' que luego se refina progresivamente.
CyberFonic el
2

Yo uso Test-Driven Design (TDD). Escribir la prueba primero realmente ayuda a llevarlo a un diseño limpio y correcto. Ver http://en.wikipedia.org/wiki/Test-driven_development .

David Allen
fuente
2
TDD ayuda a visualizar inicialmente su sistema como un cuadro negro con su entrada y salida de muestra. Pero per se no le ayuda a idear el diseño del sistema. Me refería a que para la prueba de la unidad primero tienes que encontrar la interfaz de clase para probar
Vicente Bolea
2

Aprende patrones de diseño . Ha sido mi revolución personal los últimos dos años con respecto a la POO. Consigue un libro. Te recomendaría este:

Head First Patrones de diseño

Está en Java pero puede ser extensible a cualquier lenguaje.

David Espart
fuente
1

Honestamente, un buen paso sería retroceder y observar el diagrama de flujo y el diagrama de secuencia. Hay un montón de buenos sitios que le muestran cómo hacerlo. Encuentro que es invaluable cuando veo cómo quiero dividir un programa en clases, ya que sé exactamente qué necesita el programa ingresado, calculado y generado, y cada paso se puede dividir en una parte del programa.

usuario133018
fuente
1
Me gustan los diagramas de flujo para cuando me quedo atrapado en un problema. A veces me ayuda a pensar sobre el problema de una manera diferente.
user133018
En lugar de los diagramas de flujo o los diagramas de flujo , los "Diagramas de flujo de datos" (DFD) son mucho más de alto nivel: se parecen más a un diagrama de implementación UML y son adecuados para obtener información sobre la funcionalidad del sistema (es decir, la entrada de datos del sistema y salida de datos, almacenamiento de datos internos y externos y procesamiento de datos), y arquitectura. Los diagramas de flujo son (en mi humilde opinión) más cercanos al modelado de una sola función con sentencias if-then-else.
ChrisW
Sí, uso la mayor parte del tiempo, generalmente, los diagramas de flujo son principalmente para cuando estoy tratando de resolver un problema particular.
user133018
El uso de carriles soluciona muchos de los problemas con los diagramas de flujo. Descubrí que usar un diagrama de secuencia por escenario funciona mejor. Cada escenario cubre una ruta específica a través del árbol de decisión para que no haya IF en el flujo. Si desea tener un solo diagrama con todo el flujo, deberá incluir los puntos de decisión, pero se desordenará rápidamente, especialmente si desea incluir la asignación de responsabilidades.
Kelly S. French
1

Una técnica útil es relacionar la descripción de su problema único con algo que puede encontrar en el mundo real. Por ejemplo, está modelando un complejo sistema de atención médica que arrasará con el mundo. ¿Hay algún ejemplo al que puedas recurrir para modelar esto?

En efecto. Observe cómo funcionaría la farmacia secundaria o la habitación del médico.

Traiga su problema de dominio a algo comprensible para usted; algo con lo que te puedas identificar.

Luego, una vez que los "jugadores" dentro del dominio comienzan a parecer obvios, y usted comienza a modelar su código, opte por un enfoque de modelado "proveedor-consumidor", es decir, su código es el "proveedor" del modelo, y usted es el "consumidor" ".

Relacionarse con el dominio y comprenderlo a un alto nivel es una parte clave de cualquier diseño.

Mike J
fuente
1

Durante mis aventuras de diseño de estructuras de clase, me di cuenta de que es muy útil comenzar escribiendo un pseudocódigo. Eso significa: empiezo por "escribir" algunos fragmentos generales del código de la aplicación al más alto nivel, juego con él y descubro los elementos que aparecen, de hecho, los elementos que a mí, como programador, me gustaría usar. Es un muy buen punto de partida para diseñar la estructura general de los módulos y sus interacciones. Después de algunas iteraciones, toda la estructura comienza a parecerse más a un sistema completo de clases. Es una forma muy flexible de diseñar partes de código. Puede llamarlo un diseño orientado al programador.

Darius
fuente