Creo que hay algunos factores que aún no se han mencionado.
En primer lugar, al menos en "OOP puro" (por ejemplo, Smalltalk) donde todo es un objeto, debe torcer su mente en una configuración bastante poco natural para pensar en un número (por un solo ejemplo) como un objeto inteligente en lugar de solo un valor, ya que en realidad 21
(por ejemplo) realmente es solo un valor. Esto se vuelve especialmente problemático cuando, por un lado, le dicen que una gran ventaja de OOP es modelar la realidad más de cerca, pero comienza tomando lo que se parece mucho a una vista inspirada en el LSD, incluso de las partes más básicas y obvias de realidad.
En segundo lugar, la herencia en OOP tampoco sigue muy de cerca los modelos mentales de la mayoría de las personas. Para la mayoría de las personas, clasificar las cosas más específicamente no tiene ningún lugar cercano a las reglas absolutas necesarias para crear una jerarquía de clases que funcione. En particular, crear un class D
que herede de otro class B
significa que los objetos de class D
compartir absolutamente, positivamente todas las características de class B
. class D
puede agregar características nuevas y diferentes, pero todas las características de class B
deben permanecer intactas.
Por el contrario, cuando las personas clasifican las cosas mentalmente, generalmente siguen un modelo mucho más flexible. Por ejemplo, si una persona establece algunas reglas sobre lo que constituye una clase de objetos, es bastante típico que casi cualquier regla se pueda romper siempre que se sigan suficientes otras reglas. Incluso las pocas reglas que realmente no se pueden romper casi siempre se pueden "estirar" un poco de todos modos.
Solo por ejemplo, considere "auto" como una clase. Es bastante fácil ver que la gran mayoría de lo que la mayoría de la gente piensa como "autos" tiene cuatro ruedas. Sin embargo, la mayoría de las personas ha visto (al menos una foto de) un automóvil con solo tres ruedas. Algunos de nosotros de la edad adecuada también recordamos un auto de carreras o dos de principios de los 80 (más o menos) que tenía seis ruedas, y así sucesivamente. Esto nos deja básicamente con tres opciones:
- No afirme nada acerca de cuántas ruedas tiene un automóvil, pero esto lleva a la suposición implícita de que siempre será 4, y el código es probable que se rompa por otro número.
- Afirma que todos los autos tienen cuatro ruedas, y simplemente clasifica esos otros como "no autos" aunque sabemos que realmente lo son.
- Diseñe la clase para permitir la variación en el número de ruedas, por si acaso, aunque existe una buena posibilidad de que esta capacidad nunca sea necesaria, utilizada o probada adecuadamente.
La enseñanza sobre la OOP a menudo se centra en la construcción de grandes taxonomías, por ejemplo, fragmentos de lo que sería una jerarquía gigante de toda la vida conocida en la tierra, o algo así en ese orden. Esto plantea dos problemas: en primer lugar, tiende a llevar a muchas personas a centrarse en grandes cantidades de información que es totalmente irrelevante para la pregunta en cuestión. En un momento vi una discusión bastante larga sobre cómo modelar razas de perros, y si (por ejemplo) "caniche miniatura" debería heredar de "caniche de tamaño completo", o viceversa, o si debería haber una base abstracta "Caniche "clase, con" caniche de tamaño completo "y" caniche miniatura "ambos heredados de él. Lo que todos parecían ignorar era que se suponía que la aplicación debía hacer un seguimiento de las licencias para perros,
En segundo lugar, y casi importante, lleva a centrarse en las características de los elementos, en lugar de centrarse en las características que son importantes para la tarea en cuestión. Conduce a modelar las cosas como son, donde (la mayoría de las veces) lo que realmente se necesita es construir el modelo más simple que satisfaga nuestras necesidades, y usar la abstracción para adaptarse a las subclases necesarias para adaptarse a la abstracción que hemos construido.
Finalmente, diré una vez más: lentamente estamos siguiendo el mismo camino tomado por las bases de datos a lo largo de los años. Las primeras bases de datos siguieron el modelo jerárquico. Aparte de centrarse exclusivamente en los datos, esta es una herencia única. Durante un breve período de tiempo, algunas bases de datos siguieron el modelo de red, esencialmente idénticas a la herencia múltiple (y visto desde este ángulo, las interfaces múltiples no son lo suficientemente diferentes de las múltiples clases base para notar o preocuparse).
Sin embargo, hace mucho tiempo, las bases de datos convergían en gran medida en el modelo relacional (y aunque no son SQL, en este nivel de abstracción las bases de datos "NoSQL" actuales también son relacionales). Las ventajas del modelo relacional son lo suficientemente conocidas como para no molestarme en repetirlas aquí. Solo señalaré que el análogo más cercano del modelo relacional que tenemos en la programación es la programación genérica (y lo siento, pero a pesar del nombre, los genéricos de Java, por ejemplo, realmente no califican, aunque son un pequeño paso en el dirección correcta).