- Fundamentos de la programación orientada a objetos: Abstracción
- Fundamentos de la programación orientada a objetos: Encapsulación
- Fundamentos de la programación orientada a objetos: Herencia
- Fundamentos de la programación orientada a objetos: Polimorfismo
- Fundamentos de la programación orientada a objetos: Composición (diseño)
- Definición de clases
- Derechos de acceso
- Constructores: por defecto, paramétricos y de copia
- Destructores
- Autorreferencia: esto
- Herencia
- Creación dinámica de objetos: nuevo y suprimir
- Punteros
- Métodos virtuales (virtual y override)
- Miembros estáticos
- Tipos anidados, espacios de nombres y operador de contexto '::'
- Dividir definición y declaración de clase
- Clases abstractas e interfaces
- Sobrecarga de operadores
- Conversión de tipos de objeto: dynamic_cast y puntero void *
- Punteros, referencias y const
- Gestión de la herencia: final y delete
Fundamentos de la programación orientada a objetos: composición (diseño)
Cuando se diseñan programas utilizando la programación orientada a objetos, existe el problema de encontrar la división óptima (según unas características dadas) en clases y relaciones entre ellas. El término «composición» puede resultar ambiguo y a menudo se utiliza con distintos significados, incluido uno de los casos especiales de «componer» clases. Esta digresión es necesaria porque, cuando se lee otra literatura informática, pueden encontrarse diferentes interpretaciones del término «composiciones», tanto en un sentido generalizado como en un sentido más restringido. Intentaremos explicar este concepto, especificando el significado de los términos en cada caso (cuándo se refiere al «diseño o desarrollo del proyecto» en general de la interfaz de software, y cuándo se refiere a la «agregación compositiva»).
Así, la clase, como sabemos, consta de campos (propiedades) y métodos. Las propiedades, a su vez, pueden describirse mediante tipos personalizados, es decir, pueden ser objetos de otra clase. Hay varias formas de conectar lógicamente estos objetos:
- Composición (completa inclusión o agregación compositiva) de objetos-campos en un objeto propietario. La relación de tales objetos se describe mediante la relación «todo-parte», y la parte no puede existir fuera del todo. Se dice que el objeto propietario «tiene un» objeto de propiedad, y el objeto de propiedad es una «parte de» el objeto propietario. El propietario crea y destruye sus partes. Al borrar el propietario se eliminan todas sus partes; el propietario no puede existir sin partes.
- Agregación de objetos-campos por parte del objeto propietario; esto es una inclusión «más suave». Aunque la relación también se describe como «todo-parte», el propietario sólo contiene referencias a partes que pueden asignarse, modificarse y existir aisladas del todo. Además, una pieza puede utilizarse en varios «propietarios».
- Asociación, es decir, una conexión unidireccional o bidireccional de objetos independientes que tiene un significado aplicado arbitrario; se dice que un objeto «utiliza» a otro.
Otro tipo de relación a tener en cuenta es «es un(a)», abordada anteriormente en la herencia.
Un ejemplo de inclusión total es un coche y su motor. Aquí, un coche se entiende como un medio de transporte en toda regla. Pero no es así si no tiene motor. Y un motor determinado pertenece sólo a un coche a un mismo tiempo. Las situaciones en las que todavía no hay motor en el coche (en la fábrica) o este ya no existe (en el taller de reparación de coches) son equivalentes a que hayamos roto el código fuente del programa.
Un ejemplo de agregación es la composición de grupos de alumnos para los estudios de determinadas asignaturas: un grupo para cada asignatura incluye a varios alumnos, y cualquiera de ellos puede pertenecer a otros grupos (si estudia varias asignaturas). El grupo «tiene» estudiantes. La salida de un alumno del grupo no afecta al proceso educativo del grupo (el resto sigue estudiando).
Por último, para demostrar la idea de asociación, consideremos un ordenador y una impresora. Podemos decir que el ordenador utiliza la impresora para imprimir. La impresora puede encenderse o apagarse según sea necesario, y la misma impresora puede utilizarse desde distintos ordenadores. Todos los ordenadores e impresoras son independientes entre sí, pero pueden compartirse.
En cuanto a las características que suelen guiar el diseño de las clases, las más famosas son:
- DRY (Don't repeat yourself): en lugar de ello, mueva las partes comunes a clases padre (posiblemente abstractas).
- SRP (Single Responsibility Principle): una clase debe realizar una sola tarea, y si no es así, hay que dividirla en otras más pequeñas.
- OCP (Open-Closed Principle): «escribir código abierto a ampliación pero cerrado a modificación». Si hay varias opciones de cálculo codificadas en la clase X y pueden aparecer otras nuevas, cree una clase base (abstracta) para un cálculo independiente y cree opciones específicas («extensión» de la funcionalidad) a partir de ella,conectadas a la clase X sin modificarla.
Éstas son sólo algunas de las mejores prácticas del diseño de clase. Una vez que domine los fundamentos de la programación orientada a objetos en el ámbito de este libro, puede ser útil consultar otras fuentes de información especializadas en el tema, ya que proporcionan soluciones ya preparadas para la descomposición de objetos en muchas situaciones comunes.