que programacion poo orientada objetos objeto metodos encapsulamiento ejemplos ejemplo constructores codigo clases c++ oop

poo - programacion orientada a objetos c++ ejemplos



Secreto para lograr un buen diseño OO (8)

  1. (muy) Diseño simple, pero no simplista (diseño lo suficientemente simple si lo prefiere): K.I.S.S .
  2. Prefiere jerarquías planas, evita jerarquías profundas.
  3. La separación de las preocupaciones es esencial.
  4. Considere otros "paradigmas" que OO cuando no parezca lo suficientemente simple o elegante.
  5. Más generalmente: D.R.Y. y Y.A.G.N.I te ayudan a lograr 1.

Soy programador de c ++, y estoy deseando aprender y dominar el diseño OO. He realizado muchas búsquedas y, como todos sabemos, hay un montón de material, libros, tutoriales, etc. sobre cómo lograr un buen diseño OO. Por supuesto, entiendo que un buen diseño es algo que solo puede aportar mucha experiencia, talento individual, brillantez o, de hecho, incluso por mera suerte (¡exageración!).

Pero seguro que todo comienza con un comienzo sólido y algunos conceptos básicos sólidos. ¿Puede alguien ayudarme señalando el material correcto sobre cómo comenzar esta búsqueda de aprendizaje diseñando desde la etapa de identificación de objetos, clases, etc. hasta el escenario? de utilizar patrones de diseño. Habiendo dicho que soy programador pero no he tenido experiencia en el diseño. ¿Puede ayudarme a que alguien me ayude en esta transición de un programador a un diseñador? Cualquier consejo, sugerencia, consejo será útil.

[Editar] Gracias por los enlaces y las respuestas, necesito involucrarme en eso :) Como mencioné antes, soy programador de C ++ y entiendo los conceptos básicos de OO como tales, como herencia, abstracción, polimorfismo y haber escrito el código en C ++ también comprende algunos de los patrones de diseño. Lo que no entiendo es el proceso de pensamiento básico con el que se debe abordar un requisito. El problema que me parece es cómo evaluar y decidir qué clases se deben hacer y cómo definir o concluir las relaciones que deben tener entre sí. Conociendo los conceptos (en cierta medida) pero no saber cómo aplicarlos tener :( ¿Alguna sugerencia sobre eso?


  1. No-solo-trabajo. Los buenos diseños rara vez son creados por una sola persona. Hable con sus colegas. Discute tu diseño con otros. Y aprender.
  2. No seas demasiado inteligente. Una jerarquía compleja con 10 niveles de herencia rara vez es un buen diseño. Asegúrese de que puede explicar claramente cómo funciona su diseño. Si no puede explicar los principios básicos en 5 minutos, su diseño probablemente sea demasiado complejo.
  3. Aprende trucos de los maestros: Alexandrescu, Meyers, Sutter, GoF.
  4. Prefiere la extensibilidad sobre la perfección. El código fuente escrito hoy será insuficiente en 3 años. Si escribe su código para que sea perfecto ahora, pero inextensible, tendrá un problema más adelante. Si escribe su código para que sea extensible (pero no perfecto), aún podrá adaptarlo más tarde.

Como dijiste, no hay nada como la experiencia. Puedes leer todos los libros existentes en el planeta sobre esto, todavía no serás tan bueno como si lo practicaras.

Entender la teoría es bueno, pero en mi humilde opinión, no hay nada como la experiencia. Creo que la mejor manera de aprender y entender las cosas completamente es aplicarlas en algunos proyectos.

Allí enfrentará dificultades, aprenderá a resolverlas, a veces quizás con una mala solución: pero aún así aprenderá. Y si en cualquier momento algo te molesta y no encuentras la manera de resolverlo bien, ¡estaremos aquí para ayudarte! :)


En pocas palabras: codifique, critique, busque una solución conocida, impleméntela y vuelva al primer paso hasta que esté (más o menos) satisfecho.

Como suele suceder, la respuesta a este tipo de pregunta es: depende. Y en ese caso, depende de cómo aprendas las cosas. Le diré qué es lo que me funciona, porque me enfrento al problema que describe, pero no funcionará con todos y no diría que es "la respuesta perfecta".

Empiezo a codificar algo, no demasiado simple, no demasiado complejo. Entonces, miro el código y pienso: está bien, ¿qué está mal? Para eso, puedes usar los primeros tres "principios SOLIDOS":

  • Una sola responsabilidad (¿todas sus clases tienen un propósito único?)
  • Principio de apertura / cierre (si desea agregar un servicio, sus clases pueden extenderse con herencia, pero no es necesario modificar las funciones básicas o sus clases actuales).
  • Sustitución de Liskov (está bien, no puedo explicar esto simplemente, y aconsejaría leer sobre esto).

No trates de dominarlos y entender todo sobre ellos. Solo úselos como guía para criticar su código. Piensa principalmente en "¿qué pasa si quiero hacer esto ahora?". "¿Qué pasa si trabajo para un cliente y él quiere agregar esto o aquello?". Si su código se adapta perfectamente a cualquier situación (lo cual es casi imposible), es posible que haya alcanzado un muy buen diseño.

Si no es así, considere una solución. Qué harías ? Intenta venir con una idea. Luego, lea sobre patrones de diseño y encuentre uno que pueda responder a su problema. Vea si coincide con su idea: a menudo, es la idea que tuvo, pero mejor expresada y desarrollada. Ahora, trata de implementarlo. Tomará tiempo, a menudo fallará, es frustrante y eso es normal.

El diseño tiene que ver con la experiencia, pero la experiencia se adquiere al criticar tu propio código. Así es como entenderás el diseño, no como una buena idea, sino como la base para un código sólido. No es suficiente saber "de acuerdo, un buen código tiene eso y aquello". Es mucho mejor haber experimentado por qué, haber fallado y ver qué es lo que está mal. El problema con el patrón de diseño es que son muy abstractos. Mi método es una forma (probablemente no la única ni la mejor) de hacer que sean menos abstractos para usted.


Los conceptos centrales en mi mente son:

  1. Encapsulación: mantenga la mayor parte de su objeto oculto tanto de los ojos curiosos como de los dedos pegajosos del mundo exterior.
  2. Abstracción: oculte la mayor parte del funcionamiento interno de su objeto de las mentes simples del código que necesita usar sus objetos

Todos los demás conceptos, como herencia, polimorfismo y patrones de diseño, tratan de incorporar los dos conceptos anteriores y todavía tienen objetos que pueden resolver problemas del mundo real.


Puedo aconsejarle el libro "Head First Design Patterns" (buscar en Amazon). Es un buen punto de partida, antes de sumergirse seriamente en la biblia de la pandilla de los cuatro, y muestra los principios de diseño y los patrones más utilizados.


Voy a citar a Marcus Baker sobre cómo lograr un buen diseño de OO en una publicación del foro aquí: http://www.sitepoint.com/forums/showpost.php?p=4671598&postcount=24

1) Tomar un hilo de un caso de uso.

2) Ponlo en práctica de alguna manera.

3) Toma otro hilo.

4) Ponlo en práctica de alguna manera.

5) Busque cosas en común.

6) Factoriza el código para que las características comunes se recojan en funciones. Apunta a la claridad del código. No hay globales, pasa todo.

7) Cualquier bloque de código que no esté claro, también se agrupa en una función.

8) Implemente otro subproceso de cómo, pero use sus funciones existentes si son entradas instantáneas.

9) Una vez trabajando, factoriza nuevamente para eliminar la duplicación. A estas alturas, es posible que descubra que está pasando una cantidad similar de cosas de una función a otra. Para eliminar la duplicación, mueva estos a los objetos.

10) Implementa otro hilo una vez que tu código sea perfecto.

11) Refactorizar para evitar la duplicación hasta aburrir.

Ahora el bit OO ...

12) A estas alturas, deberían estar surgiendo algunos roles superiores candidatos. Agrupa esas funciones en roles por clase.

13) Refactorizar nuevamente con el objetivo de claridad. Ninguna clase más grande que un par de páginas de código, ningún método más de 5 líneas. No hay herencia a menos que la variación sea solo unas pocas líneas de código.

A partir de este punto puedes hacer un ciclo ...

14) Implementar un hilo de uso en cualquier caso antiguo.

15) Refactor como el anterior. La refactorización incluye renombrar objetos y clases a medida que sus significados evolucionan.

16) Repetir hasta aburrir.

Ahora los patrones de cosas!

Una vez que tenga un par de docenas de clases y bastante funcionalidad en funcionamiento, puede observar que algunas clases tienen un código muy similar, pero no una división obvia (no, no utilice la herencia). En este punto, consulte los libros de patrones para ver las opciones para eliminar la duplicación. Pista: probablemente quieras "Estrategia".

Las siguientes repeticiones ...

17) Implementar otro subproceso de un caso de uso de cualquier viejo.

18) Métodos de refactorización de hasta cinco líneas o menos, clases de hasta 2 páginas o menos (preferiblemente mucho menos), busque patrones para eliminar la duplicación de niveles superiores si realmente hace que el código sea más limpio.

19) Repita hasta que sus constructores de nivel superior tengan muchos parámetros o se encuentren usando "nuevo" mucho para crear objetos dentro de otros objetos (esto es malo).

Ahora necesitamos limpiar las dependencias. Cualquier clase que trabaje no debe usar "nuevo" para crear cosas dentro de sí mismo. Pasa esos sub objetos desde fuera. A las clases que no realizan trabajos mecánicos se les permite usar el operador "nuevo". Simplemente ensamblan cosas, las llamaremos fábricas. Una fábrica es un papel en sí mismo. Una clase debe tener un solo rol, por lo tanto, las fábricas deben ser clases separadas.

20) Factoriza las fábricas.

Ahora repetimos otra vez ...

21) Implementar otro hilo de un caso de uso cualquiera antiguo como.

22) Métodos de refactorización de hasta cinco líneas o menos, clases de hasta 2 páginas o menos (preferiblemente mucho menos), busque patrones para eliminar la duplicación de niveles más altos si realmente hace que el código sea más limpio, asegúrese de usar clases separadas para las fábricas.

23) Repita hasta que sus clases de nivel superior tengan una cantidad excesiva de parámetros (por ejemplo, 8+).

Probablemente ya hayas terminado. Si no, busque el patrón de inyección de dependencia ...

24) Cree (solo) sus clases de nivel superior con un inyector de dependencia.

Entonces puedes repetir otra vez ...

25) Implementar otro subproceso de un caso de uso cualquiera antiguo como.

26) Métodos de refactorización de hasta cinco líneas o menos, clases de hasta 2 páginas o menos (preferiblemente mucho menos), busque patrones para eliminar la duplicación de niveles más altos si realmente hace que el código sea más limpio, asegúrese de usar clases separadas para las fábricas. pasar las dependencias de nivel superior (incluidas las fábricas) a través de DI.

27) Repetir.

En cualquier etapa de esta heurística probablemente querrá echar un vistazo al desarrollo basado en pruebas. Como mínimo, detendrá las regresiones mientras usted refactoriza.

Obviamente, este es un proceso bastante simple, y la información contenida en él no debe aplicarse a todas las situaciones, pero creo que Marcus lo entiende bien, especialmente con respecto al proceso que se debe usar para diseñar un código OO. Después de un tiempo, comenzarás a hacerlo de forma natural, simplemente se convertirá en una segunda naturaleza. Pero mientras aprendes a hacerlo, este es un gran conjunto de pasos a seguir.


No hay secreto. Es sudor, no magia.

No se trata de hacer una cosa bien. Está equilibrando muchas cosas que no deben salir mal. A veces, trabajan sincronizados, a veces, trabajan uno contra el otro. El diseño es solo un grupo de estos aspectos. El mejor diseño no ayuda si el proyecto falla (por ejemplo, porque nunca se envía).

La primera regla que propondría es:

1. No hay seguimientos absolutos directamente de las "muchas cosas para equilibrar. DRY, YAGNI, etc., son pautas que seguirlas estrictamente no puede garantizar un buen diseño, si van seguidas de la letra pueden hacer que su proyecto falle.

Ejemplo: SECO Uno de los principios más fundamentales, sin embargo, los estudios muestran que la complejidad de los fragmentos de código pequeños aumenta en un factor de 3 o más cuando se aíslan, debido a la verificación previa / posterior de la condición, el manejo de errores y la generalización a múltiples casos relacionados. Por lo tanto, el principio debe debilitarse a "SECO (al menos, no demasiado)": cuándo y cuándo no es la parte difícil.

La segunda regla no es muy común:

2. Una interfaz debe ser más simple que la implementación.

Suena trivial para ser pegadizo. Sin embargo, hay mucho que decir al respecto:

La premisa de OO era administrar los tamaños de los programas que ya no se podían administrar con programación estructurada. El mecanismo principal es encapsular la complejidad: podemos ocultar la complejidad detrás de una interfaz más simple y luego olvidarnos de esa complejidad.

La complejidad de la interfaz implica la documentación, las especificaciones de manejo de errores, las garantías de rendimiento (o su ausencia), etc. Esto significa que, por ejemplo, reducir la declaración de la interfaz mediante la introducción de casos especiales no es una reducción de la complejidad, solo un orden aleatorio.

3-N Aquí es donde pongo la mayoría de las otras menciones, que ya se han explicado muy bien.

Separación de preocupaciones, KISS, principio SOLID , SECO, aproximadamente en ese orden.

¿Cómo construir software de acuerdo con estas pautas?

Las pautas anteriores ayudan a evaluar una pieza de código. Desafortunadamente, no hay una receta para llegar allí. "Experimentado" significa que tiene una buena idea de cómo estructurar su software, y algunas decisiones simplemente se sienten mal. Tal vez todos los principios son solo racionalizaciones después del hecho.

El camino general es dividir un sistema en responsabilidades, hasta que las piezas individuales sean manejables.

Hay procesos formales para eso, pero estos simplemente resuelven el hecho de que lo que hace que un componente bueno y aislado sea ​​una decisión subjetiva. Pero al final, eso es por lo que nos pagan.

Si tienes una idea aproximada de todo el sistema, no está mal comenzar con una de estas piezas como una semilla y convertirlas en un "núcleo". De arriba a abajo y de abajo a arriba no son antípodas.

Práctica práctica práctica. Cree un programa pequeño, hágalo funcionar, cambie los requisitos, haga que se ejecute de nuevo. La parte de "requisitos cambiantes" que no necesita entrenar mucho, tenemos clientes para eso.

Revisiones posteriores al proyecto : trate de acostumbrarse a ellas incluso para sus proyectos personales. Después de que esté sellado, listo, evalúa lo que era bueno, lo que era malo. Considere el código fuente que se desechó, es decir, no vea esa sesión como "¿qué debería arreglarse?"

La Ley de Conway dice que "Un sistema refleja la estructura de la organización que lo construyó". Eso se aplica a la mayoría del software complejo que he visto, y los estudios formales parecen confirmar eso. Podemos derivar algunos bits de información de eso:

  • Si la estructura es importante, también lo son las personas con las que trabajas.
  • O tal vez la estructura no es tan importante. No hay una estructura correcta (solo hay que evitar muchas incorrectas)