inheritance composition testability

inheritance - Herencia vs. Composición para la testabilidad.



composition testability (5)

Al diseñar mis objetos, encuentro que la composición es una mejor opción desde la perspectiva de la capacidad de prueba. La razón es que puedo simular partes de la estructura de la composición si es necesario, mientras ejecuto pruebas unitarias. Esto no es posible si tengo una jerarquía de herencia.

Me gustaría saber si otros también han encontrado que esta es una razón para preferir la composición. Además, ¿en qué otros errores de probabilidad se metió porque se usó la herencia?


Creo que cuanto más empieces a desarrollar utilizando patrones de diseño, encontrarás más y más a menudo dónde se favorecerá la composición sobre la herencia. De hecho, creo en el libro Head First: Design Patterns que " Favorecer la composición sobre la herencia " es uno de los principios de diseño principales.

Su ejemplo de poder simular partes de la composición para la prueba es probablemente uno de los mejores ejemplos posibles.

Edición : aunque el principio básico en los patrones de diseño es favorecer la composición sobre la herencia, eso no significa que no haya patrones de diseño que utilicen la herencia donde se necesita. Otro ejemplo básico es el patrón decorador, en el que se codifica hacia una superclase abstracta (aunque esto es para la coincidencia de tipos y no para implementar una relación "is-a").


Creo que la razón principal por la que la composición es más fácil de probar es que la herencia (implementación) tiende a crear clases muy acopladas que son más frágiles (clase base frágil) y más difíciles de probar de forma aislada.

La herencia definitivamente tiene sus usos, pero cada vez prefiero la composición a la herencia.


El libro Gang of Four Design Patterns trata básicamente de por qué preferir la composición sobre la herencia y ofrece muchas formas de hacerlo. Algunas razones:

  1. de clases aumenta la complejidad del código base

  2. En muchos idiomas nuevos, la herencia está limitada a una clase, mientras que usted puede componer todo lo que quiera
  3. Las clases base no se pueden cambiar en tiempo de ejecución (esencialmente el problema detrás de lo que se está ejecutando).

No es una situación de uno u otro. No son competidores.

La herencia es bastante fácil de probar por unidad, también. Sin embargo, a veces se requieren clases concretas simuladas para probar una superclase abstracta.

La herencia puede ser fácilmente utilizada incorrectamente. Algunos diseños parecen situaciones "is-a", pero en realidad no lo son, tienen más matices. A veces es realmente "de comportamiento" donde necesita algún tipo de composición (una Estrategia , por ejemplo) para separar el comportamiento de otros atributos.


"Favorecer la composición de objetos sobre la herencia de clase" es en realidad del libro GoF Esta conversation con Erich Gamma describe esta idea del libro.

Un patrón importante que requiere herencia es un patrón de método de plantilla. Este patrón es muy usado, por lo que la herencia está aquí para quedarse. Otro patrón común que usaría la herencia es el patrón compuesto. El punto que trato de señalar es que no descarto la herencia en absoluto, pero espero que quede claro solo con ver tantas API comunes de todos modos ...