¿Por qué no hay una definición coherente de conceptos esenciales para OOP?

12

Soy muy nuevo en programación y estoy un poco confundido de leer / escuchar diferentes convenciones de diferentes fuentes:

¿La programación orientada a objetos tiene 4 o 5 conceptos?

Como recién llegado, entiendo que estos son los 5 conceptos:

  • Abstracción
  • Herencia
  • Encapsulación
  • Polimorfismo
  • Modularidad

Entonces, ¿cómo es que no encuentro una definición más "estricta" y parece que hay varios arreglos de estos conceptos?


fuente
77
Tal vez porque eso no es como las matemáticas (algunos conceptos en CS lo son, pero creo que OOP no pertenece a esta categoría), por lo que no hay definiciones estrictas para empezar. Entonces, por ejemplo, ¿cuán importante es la 'modularidad'? ¿Es realmente tan especial para OOP que tenemos que mencionarlo o sería algo que sucede solo si aplicamos los otros cuatro correctamente? Algunas listas agregan 'jerarquía', pero ¿es esto realmente algo extra o simplemente se deriva de la herencia y el polimorfismo?
thorsten müller
66
Un consejo: como programador muy nuevo, no deberías preocuparte tanto por comprender la terminología y la teoría. Reúna primero una experiencia práctica de programación, y se volverá mucho más obvio de qué están hablando estas personas.
Philipp
99
Otra cosa es que la POO está cambiando con el tiempo. Una gran concentración en los primeros días de C ++ (sé que la POO se remonta más atrás que eso) estaba en herencia y polimorfismo. El enfoque de hoy es mucho más en la abstracción y la encapsulación.
Doblado
3
Aquí puede encontrar una discusión interesante sobre la falta de precisión en la definición de OO: c2.com/cgi/wiki?NobodyAgreesOnWhatOoIs
MichelHenrich

Respuestas:

26

La razón por la que encuentra diferentes explicaciones de lo que significa la programación orientada a objetos es porque no hay una sola persona u organización con la autoridad para formular una definición estrictamente aplicable universalmente.

La programación orientada a objetos no es un estándar ISO o una ley científica. Es una filosofia. Y como con todas las filosofías, hay todo tipo de interpretaciones diferentes y ninguna interpretación es universalmente aplicable. Cuando lee un texto que le dice qué conceptos debe seguir al diseñar una arquitectura de software, debe ver esto como una guía basada en las opiniones que formó el autor durante su experiencia profesional, y no como una verdad universal.

Philipp
fuente
12

¿La programación orientada a objetos tiene 5 o 4 componentes?

Como otros han mencionado, "OO" en realidad no tiene ningún componente , porque es una forma de pensar sobre el modelado de soluciones a problemas y no un conjunto de herramientas ni un conjunto de procesos claramente definidos.

Como recién llegado, entiendo que estos son los 5 componentes:

¿Abstracción, herencia, encapsulación, polimorfismo y modularidad?

La herencia y el polimorfismo son características del lenguaje de programación. Es bueno que comprenda esto, pero recuerde que son herramientas (lo que significa que, como con cualquier otra herramienta, solo deben usarse para resolver problemas específicos y no tratarse como una meta o algo por lo que luchar). Puede (y con frecuencia debería) escribir el código "OO" sin usar ninguno de ellos. Algunos de los mejores códigos "OO" que he visto utilizan muy poco la herencia o el polimorfismo.

La abstracción, la encapsulación y la modularidad tienen menos que ver con el código y más con la forma en que ve un problema, la forma en que intenta comprender ese problema y la forma en que diseña y estructura su solución en código.

Además, esas ideas de diseño no son exclusivas de "OO". Lo más probable es que probablemente los entienda ahora en un nivel básico, que podría incluir la posibilidad de explicar una definición perfecta de libro de texto y aplicarlos a problemas algo no triviales; aunque una prueba más profunda de comprensión se le está dando un problema complejo muy grande y cuánta complejidad puede manejar.

Otra prueba de comprensión es el enfoque que utiliza para resolver un problema; y los recién llegados a "OO", a quienes a menudo se les enseña sobre OO en términos de modelado de datos (porque así es como la mayoría de las personas solían entenderlo en la década de 1990), y a menudo terminan centrados en los aspectos incorrectos de un problema, es decir, se enfocan demasiado en los datos, y no se centran lo suficiente en el comportamiento.

Por ejemplo, los ejemplos clásicos a menudo se refieren a entidades tales como Dog, Cat, Elephant, Seagull, Shark, etc. Los recién llegados a "OO" a menudo miro esos ejemplos e inmediatamente pienso "Oh, necesito una entidad de base llamada Animal" , e incluso pueden terminar con otra entidades intermedias como Mammaly Amphibianen una jerarquía de herencia ordenada, con diferentes atributos en cada una.

Si bien esa forma de pensar demuestra una comprensión muy básica de varios conceptos de OO, un programador de OO experimentado nunca lo abordaría así ni llegaría a esa conclusión (y en realidad se quejaría de que no tienen suficiente información), porque ese enfoque demuestra Entidad modelado en lugar de modelado OO, y porque el ejemplo artificial no dice nada sobre el comportamiento de esos animales (y muchas personas argumentarán en estos días que la esencia de OO está en el comportamiento y la funcionalidad).

El camino para aprender sobre "OO" tradicionalmente implica pasar tiempo construyendo las abstracciones equivocadas cuando no sabes nada (o muy poco) sobre el comportamiento del problema que estás modelando, o cuando cometes el error de enfocar tu atención en entidades en lugar de funcionalidad, aunque parte de eso se debe a que muchos libros, cursos y tutoriales en línea escritos a lo largo de los años han estado (mal) guiando a los estudiantes por ese camino durante mucho tiempo (aunque la marea está cambiando).

En general, gran parte de su comprensión se reducirá a la experiencia. Esos conceptos que ha aprendido hasta ahora son un buen comienzo, hay más conceptos que necesitará aprender a lo largo del camino (por ejemplo, principios "SÓLIDOS" y "SECOS"), y deberá pasar mucho tiempo poniendo la teoría a la práctica con problemas reales muy complejos antes de que sea probable que "haga clic" en su lugar.

Ben Cottrell
fuente
2
Un tiburón y una rana nadan, pero uno es un pez, el otro es un anfibio. Creo que ese ejemplo describe bien tu punto.
RubberDuck
10

El término "Orientación a objetos" fue acuñado por el Dr. Alan Kay, por lo que es la fuente autorizada sobre lo que significa, y lo define así :

OOP para mí significa solo mensajes, retención local y protección y ocultación del proceso estatal, y un enlace tardío extremo de todas las cosas.

Analicemos eso:

  • mensajería ("envío de método virtual", si no está familiarizado con Smalltalk)
  • proceso de estado debe ser
    • retenido localmente
    • protegido
    • oculto
  • atascamiento extremo de todas las cosas

En cuanto a la implementación, la mensajería es una llamada a procedimiento con retraso, y si las llamadas a procedimiento tienen un retraso, entonces no puede saber en el momento del diseño a qué va a llamar, por lo que no puede hacer suposiciones sobre la representación concreta del estado. Entonces, realmente se trata de mensajes, el enlace tardío es una implementación de mensajes y la encapsulación es una consecuencia de ello.

Más tarde aclaró que " La gran idea es 'enviar mensajes' ", y lamenta haberlo llamado "orientado a objetos" en lugar de "orientado a mensajes", porque el término "orientado a objetos" pone el foco en lo que no es importante (objetos ) y distrae de lo que es realmente importante (mensajes):

Solo un suave recordatorio de que me tomé algunas molestias en el último OOPSLA para tratar de recordarles a todos que Smalltalk NO es NO solo su sintaxis o la biblioteca de clases, ni siquiera se trata de clases. Lamento haber acuñado hace mucho tiempo el término "objetos" para este tema porque hace que muchas personas se centren en la idea menor.

La gran idea es la "mensajería": de eso se trata el núcleo de Smalltalk / Squeak (y es algo que nunca se completó en nuestra fase Xerox PARC). Los japoneses tienen una pequeña palabra - ma - para "lo que está en el medio" - tal vez el equivalente en inglés más cercano es "intersticial". La clave para crear sistemas excelentes y que se puedan desarrollar es mucho más para diseñar cómo se comunican sus módulos en lugar de cuáles deberían ser sus propiedades y comportamientos internos. Piense en Internet: para vivir, (a) tiene que permitir muchos tipos diferentes de ideas y realizaciones que están más allá de cualquier estándar único y (b) para permitir diversos grados de interoperabilidad segura entre estas ideas.

(Por supuesto, hoy en día, la mayoría de las personas ni siquiera se enfocan en objetos sino en clases, lo cual es aún más incorrecto).

La mensajería es fundamental para OO, tanto como metáfora como mecanismo.

Si le envía un mensaje a alguien, no sabe qué hace con él. Lo único que puedes observar es su respuesta. No sabe si procesaron el mensaje ellos mismos (es decir, si el objeto tiene un método), si enviaron el mensaje a otra persona (delegación / representación), incluso si lo entendieron. De eso se trata la encapsulación, de eso se trata OO. Ni siquiera puede distinguir un proxy del real, siempre que responda como espera que lo haga.

Un término más "moderno" para "mensajería" es "despacho de método dinámico" o "llamada de método virtual", pero eso pierde la metáfora y se enfoca en el mecanismo.

Por lo tanto, hay dos formas de ver la definición de Alan Kay: si la mira por sí sola, puede observar que la mensajería es básicamente una llamada a un procedimiento vinculado de forma tardía y la vinculación tardía implica la encapsulación, por lo que podemos concluir que # 1 y # 2 son en realidad redundantes, y OO se trata de enlace tardío.

Sin embargo, más tarde aclaró que lo importante es la mensajería, por lo que podemos verlo desde un ángulo diferente: la mensajería está retrasada. Ahora, si la mensajería fuera lo único posible, entonces el # 3 sería trivialmente cierto: si solo hay una cosa, y esa cosa está vinculada tarde, entonces todas las cosas están vinculadas tarde. Y una vez más, la encapsulación se deriva de la mensajería.

También se hacen puntos similares en On Understanding Data Abstraction, revisado por William R. Cook y también su Propuesta de definiciones modernas y simplificadas de "objeto" y "orientado a objetos" .

El despacho dinámico de operaciones es la característica esencial de los objetos. Significa que la operación a invocar es una propiedad dinámica del objeto en sí. Las operaciones no se pueden identificar de forma estática y, en general, no hay forma de determinar exactamente qué operación se ejecutará en respuesta a una solicitud determinada, excepto ejecutándola. Esto es exactamente lo mismo que con las funciones de primera clase, que siempre se envían dinámicamente.

¡En Smalltalk-72, ni siquiera había ningún objeto! Había sólo flujos de mensajes que quedó analizando, reescrito y redireccionados. Primero llegaron los métodos (formas estándar de analizar y redirigir las secuencias de mensajes), luego vinieron los objetos (agrupaciones de métodos que comparten algún estado privado). La herencia llegó mucho más tarde, y las clases solo se introdujeron como una forma de apoyar la herencia. Si el grupo de investigación de Kay ya hubiera conocido los prototipos, probablemente nunca habrían introducido clases en primer lugar.

Benjamin Pierce en Tipos y lenguajes de programación argumenta que la característica definitoria de la Orientación a objetos es la recursión abierta .

Entonces: según Alan Kay, OO tiene que ver con la mensajería. Según William Cook, OO tiene que ver con el envío de métodos dinámicos (que es realmente lo mismo). Según Benjamin Pierce, OO se trata de Open Recursion, lo que básicamente significa que las auto-referencias se resuelven dinámicamente (o al menos esa es una forma de pensar) o, en otras palabras, mensajes.

Como puede ver, la persona que acuñó el término "OO" tiene una visión bastante metafísica de los objetos, Cook tiene una visión bastante pragmática y Pierce una visión matemática muy rigurosa. Pero lo importante es: ¡el filósofo, el pragmático y el teórico están de acuerdo! La mensajería es el único pilar de OO. Período.

Tenga en cuenta que aquí no se menciona la herencia. La herencia no es esencial para OO. En general, la mayoría de los lenguajes OO tienen alguna forma de reutilización de implementación, pero eso no necesariamente tiene que ser herencia. También podría ser alguna forma de delegación, por ejemplo. De hecho, el Tratado de Orlando analiza la delegación como una alternativa a la herencia y cómo las diferentes formas de delegación y herencia conducen a diferentes puntos de diseño dentro del espacio de diseño de los lenguajes orientados a objetos. (Tenga en cuenta que incluso en los lenguajes que admiten la herencia, como Java, a las personas se les enseña a evitarlo, lo que nuevamente indica que no es necesario para OO).

Jörg W Mittag
fuente
1
@DavidArno Su comentario no es constructivo en absoluto. El propio Alan Kay afirma que acuñó el término "objeto" para este concepto (aunque, supongo, no el concepto en sí). Si va a contradecir una autoridad conocida sobre el tema, al menos escriba un comentario más constructivo.
Andres F.
1
@DavidArno Además, ¿el voto negativo es suyo? Entonces, ¿alguien se tomó el tiempo para escribir una lista completa de diferentes puntos de vista, de expertos conocidos, sobre lo que significa OOP, y lo rechazó porque no está de acuerdo con una sola oración? Oookay
Andres F.
2
@AndresF. Esta respuesta se puede resumir como "hay dos escuelas, sin embargo, la de Alan Kay y la de todos los demás. Porque el primero acuñó el término tiene razón automáticamente y todos los que no están de acuerdo con él están equivocados". Es una respuesta a la falacia de apelación a la autoridad. De ahí el voto negativo.
David Arno
2
En realidad, esta respuesta se puede resumir como "hay tres escuelas de pensamiento, que provienen de tres ángulos completamente diferentes y nadie está en desacuerdo con nadie, de hecho, todos están de acuerdo". El prescriptivista lingüístico diría que Alan Kay inventó el término, puede decir lo que significa y dice que significa mensajería. El descriptivista lingüístico diría, no, Alan Kay no puede decir nada, tenemos que ver cómo se usa realmente el término , y eso es lo que hizo Cook: estudió los idiomas que comúnmente se describen como OO (Java, C ++ , C #, etc.) tienen en común, y descubrió
Jörg W Mittag el
3
Una cosa: mensajería. Estudió qué idiomas comúnmente descritos como no OO carecen de los idiomas comúnmente descritos como OO, y encontró una cosa: mensajería. El teórico de la torre de marfil toma el cálculo λ y observa cuál es el conjunto más pequeño de características que uno tendría que agregar para obtener algo que comúnmente se describe como OO, y llega a una recursión abierta , que es básicamente el bloque de construcción para la mensajería. .
Jörg W Mittag
3

Como dice @Philipp, la raíz del problema es que no existe una definición oficial de lo que hace que un lenguaje de programación esté orientado a objetos. De hecho, esto es probablemente algo bueno. Hay muchas maneras de admitir la programación OO, cada una con sus propias ventajas y desventajas. La discusión sobre qué idiomas son más "OO puros" realmente no logran mucho.

Sin embargo, mirando los 5 atributos que enumeró, en mi opinión, la modularidad es definitivamente la más extraña. La modularidad es realmente un atributo de un programa, no un lenguaje de programación. A nivel lingüístico, el atributo es "soporte para la modularización", y eso típicamente toma la forma de un mecanismo de "módulos" pr "paquetes".

Pero mi verdadera objeción a Modularity es que no es clave para la programación OO o los lenguajes de programación OO, en la medida en que el lenguaje de programación arquetípico Smalltalk-80 no admite módulos en absoluto. Y cuando lo piensa, el soporte lingüístico para los módulos en muchas OOPL ampliamente utilizadas es "débil".

Los módulos están diseñados para admitir "programación en grande" ... donde su base de código se hace demasiado grande para que una sola persona la entienda completamente. Y no necesita módulos en un lenguaje de programación para modularizar su código.


No me estoy metiendo en el debate sobre los otros 4 atributos, y si (por ejemplo) qué modelos de "herencia" son pura OO. Además, aunque a Alan Kay se le atribuye haber inventado la programación OO, eso no significa necesariamente que sus definiciones de OO / y OOPL tengan primacía. Claramente este no es el caso. Es una fuente autorizada, pero hay otras fuentes que dan otras definiciones para OO y OOPL que (en la práctica) tienen mayor peso.

Stephen C
fuente
2
+1 La modularidad es de hecho ampliamente aceptada como un atributo deseable de la mayoría de los sistemas de software, independientemente del lenguaje de programación y el paradigma utilizado. Muchos lenguajes que no son OO tienen soporte para modularización.
Andres F.
+1 @AndresF. comentario. De hecho, la "programación estructurada" y el "refinamiento gradual" (una técnica para pensar la estructura del código) surge del crisol de la "complejidad creciente que resulta en un software aún peor". Había precedido a COBOL que el lenguaje no tendría una reputación tan negativa en mi humilde opinión. Y veo a OO pragmáticamente como simplemente una estructura de orden superior. Y quiero decir que sin estructura subyacente OO no es mejor que el peor COBOL.
radarbob