Cuanto más aprendo sobre diferentes paradigmas de programación, como la programación funcional, más empiezo a cuestionar la sabiduría de los conceptos de OOP como la herencia y el polimorfismo. Primero aprendí sobre la herencia y el polimorfismo en la escuela, y en ese momento el polimorfismo parecía una forma maravillosa de escribir código genérico que permitía una fácil extensibilidad.
Pero frente a la tipificación de patos (tanto dinámicos como estáticos) y características funcionales como funciones de orden superior, he comenzado a considerar la herencia y el polimorfismo como una restricción innecesaria basada en un conjunto frágil de relaciones entre objetos. La idea general detrás del polimorfismo es que escribe una función una vez, y luego puede agregar una nueva funcionalidad a su programa sin cambiar la función original; todo lo que necesita hacer es crear otra clase derivada que implemente los métodos necesarios.
Pero esto es mucho más simple de lograr a través del tipeo de pato, ya sea en un lenguaje dinámico como Python o en un lenguaje estático como C ++.
Como ejemplo, considere la siguiente función de Python, seguida de su equivalente estático de C ++:
def foo(obj):
obj.doSomething()
template <class Obj>
void foo(Obj& obj)
{
obj.doSomething();
}
El equivalente de OOP sería algo así como el siguiente código Java:
public void foo(DoSomethingable obj)
{
obj.doSomething();
}
La principal diferencia, por supuesto, es que la versión de Java requiere la creación de una interfaz o una jerarquía de herencia antes de que funcione. La versión de Java implica más trabajo y es menos flexible. Además, encuentro que la mayoría de las jerarquías de herencia del mundo real son algo inestables. Todos hemos visto ejemplos artificiales de Formas y animales, pero en el mundo real, a medida que cambian los requisitos comerciales y se agregan nuevas características, es difícil realizar cualquier trabajo antes de que realmente necesite estirar la relación "es-una" entre subclases, o bien remodelar / refactorizar su jerarquía para incluir más clases base o interfaces para acomodar nuevos requisitos. Con la escritura de pato, no necesita preocuparse por modelar nada, solo le preocupa la funcionalidad que necesita.
Sin embargo, la herencia y el polimorfismo son tan populares que dudo que sea una exageración llamarlos la estrategia dominante para la extensibilidad y la reutilización del código. Entonces, ¿por qué la herencia y el polimorfismo son tan exitosos? ¿Estoy pasando por alto algunas ventajas serias que tiene la herencia / polimorfismo sobre la tipificación de patos?
obj
no tiene undoSomething
método? ¿Se plantea una excepción? ¿No pasa nada?