This shows you the differences between two versions of the page.
wiki:ppch [2024/08/26 00:45] – created admin | wiki:ppch [2024/08/28 23:38] (current) – admin | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== Principio de Preferir Composición sobre Herencia ====== | ====== Principio de Preferir Composición sobre Herencia ====== | ||
- | + | ||
+ | Antes de explicar el principio, aclaremos que existen dos tipos de herencia: | ||
+ | |||
+ | * **Herencia de clases** (ejemplo: '' | ||
+ | |||
+ | * **Herencia de interfaces** (ejemplo: '' | ||
+ | |||
+ | Volviendo al principio, cuando la programación orientada a objetos se hizo común, en la década de los 80, hubo un impulso hacia el uso de la herencia. Se creía que el concepto podría ser una especie de bala de plata capaz de resolver los problemas de reutilización de software. Se argumentaba que jerarquías de clases profundas, con varios niveles, serían un indicativo de un buen diseño, en el cual se lograban altos índices de reutilización. Sin embargo, con el tiempo, se dio cuenta de que la herencia no era esa bala de plata. Por el contrario, la herencia tiende a introducir problemas en el mantenimiento y evolución de las clases de un sistema. Estos problemas tienen su origen en el fuerte acoplamiento que existe entre subclases y superclases, | ||
+ | |||
+ | < | ||
+ | <color black> La herencia expone a las subclases detalles de implementación de las clases padre. Por lo tanto, frecuentemente se dice que la herencia viola el encapsulamiento de las clases padre. La implementación de las subclases se vuelve tan acoplada a la implementación de la clase padre que cualquier cambio en estas últimas puede forzar modificaciones en las subclases.</ | ||
+ | </ | ||
+ | |||
+ | El principio, sin embargo, no prohíbe el uso de la herencia. Pero recomienda lo siguiente: si existen dos soluciones de diseño, una basada en herencia y otra en composición, | ||
+ | |||
+ | **Ejemplo**: | ||
+ | |||
+ | Solución via herencia: | ||
+ | <code java> | ||
+ | |||
+ | class Stack extends ArrayList { | ||
+ | ... | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Solución via composición: | ||
+ | <code java> | ||
+ | |||
+ | class Stack { | ||
+ | private ArrayList elementos; | ||
+ | ... | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | La solución mediante herencia no es recomendada por varios motivos, siendo los principales los siguientes: (1) un '' | ||
+ | |||
+ | Una segunda ventaja de la composición es que la relación entre las clases no es estática, como en el caso de la herencia. En el ejemplo, si optáramos por la herencia, la clase '' | ||
+ | |||
+ | <code java> | ||
+ | |||
+ | class Stack { | ||
+ | |||
+ | private List elementos; | ||
+ | |||
+ | Stack(List elementos) { | ||
+ | this.elementos = elementos; | ||
+ | } | ||
+ | ... | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | En el ejemplo, la estructura de datos que almacena los elementos de la pila pasó a ser un parámetro del constructor de la clase '' | ||
+ | |||
+ | Antes de concluir, se deben mencionar tres puntos adicionales a lo que discutimos sobre *Prefiera Composición a Herencia*: | ||
+ | |||
+ | - La herencia se clasifica como un mecanismo de reutilización de caja blanca, ya que las subclases suelen tener acceso a los detalles de implementación de la clase base. Por otro lado, la composición es un mecanismo de reutilización de caja negra. | ||
+ | - Un patrón de diseño que ayuda a reemplazar una solución basada en herencia por una solución basada en composición es el Patrón Decorador. | ||
+ | - Debido a los problemas discutidos en esta sección, lenguajes de programación más recientes, como **Go** y **Rust**, no incluyen soporte para herencia. |