¿Es difícil la POO porque no es natural?

86

A menudo se puede escuchar que OOP corresponde naturalmente a la forma en que las personas piensan sobre el mundo. Pero estaría totalmente en desacuerdo con esta afirmación: nosotros (o al menos yo) conceptualizamos el mundo en términos de relaciones entre las cosas que encontramos, pero el enfoque de OOP es diseñar clases individuales y sus jerarquías.

Tenga en cuenta que, en la vida cotidiana, las relaciones y acciones existen principalmente entre objetos que habrían sido instancias de clases no relacionadas en OOP. Ejemplos de tales relaciones son: "mi pantalla está encima de la mesa"; "Yo (un ser humano) estoy sentado en una silla"; "un auto está en el camino"; "Estoy escribiendo en el teclado"; "la cafetera hierve agua", "el texto se muestra en la ventana del terminal".

Pensamos en términos de verbos bivalentes (a veces trivalentes, como, por ejemplo, en "Te di flores") donde el verbo es la acción (relación) que opera en dos objetos para producir algún resultado / acción. El foco está en la acción, y los dos (o tres) objetos [gramaticales] tienen la misma importancia.

Compare eso con OOP donde primero tiene que encontrar un objeto (sustantivo) y dígale que realice alguna acción sobre otro objeto. La forma de pensar cambia de acciones / verbos que operan con sustantivos a sustantivos que operan con sustantivos: es como si todo se dijera en voz pasiva o reflexiva, por ejemplo, "la ventana de terminal muestra el texto". O tal vez "el texto se dibuja en la ventana del terminal".

No solo el foco se desplaza a los sustantivos, sino que a uno de los sustantivos (llamémoslo sujeto gramatical) se le da mayor "importancia" que al otro (objeto gramatical). Por lo tanto, uno debe decidir si dirá terminalWindow.show (someText) o someText.show (terminalWindow). Pero, ¿por qué cargar a las personas con decisiones tan triviales sin consecuencias operativas cuando uno realmente quiere decir show (terminalWindow, someText)? [Las consecuencias son operacionalmente insignificantes, en ambos casos el texto se muestra en la ventana del terminal, pero puede ser muy serio en el diseño de jerarquías de clases y una elección "incorrecta" puede conducir a un código complicado y difícil de mantener.]

Por lo tanto, diría que la forma principal de hacer POO (basada en clases, despacho único) es difícil porque ES INNATURAL y no corresponde a cómo piensan los humanos sobre el mundo. Los métodos genéricos de CLOS están más cerca de mi forma de pensar, pero, por desgracia, este no es un enfoque generalizado.

Dados estos problemas, ¿cómo / por qué sucedió que la forma actual de hacer OOP se hizo tan popular? ¿Y qué, si hay algo, se puede hacer para destronarlo?

revs zvrba
fuente
OOP es para 'programación', está hecho para que los compiladores lo disfruten. No es una forma de modelar el mundo real de ninguna manera. Es común usar ejemplos del mundo real, como la clase de animales y la clase de rectángulo, durante la enseñanza de POO, pero estos son solo ejemplos para simplificar los conceptos. Desafortunadamente, el lenguaje de programación y los paradigmas "suceden" de una manera no evolutiva y no científica. ¡Con las pocas excepciones, el proceso de diseño del lenguaje suele ser hijo de la mejor conjetura de pocas personas!
NoPuerto
3
No estaría de acuerdo con la afirmación "el enfoque de OOP es diseñar clases individuales y sus jerarquías". dado que maybie es el foco de ciertas implementaciones de OOP, pero por ejemplo he encontrado que los lenguajes dinámicos de OOP generalmente no tienen grandes jerarquías, ni siquiera clases. Bueno, la definición de OOP puede cambiar en el futuro, hay un intento de cambiar incluso el Object wcook.blogspot.com/2012/07/proposal-for-simplified-modern.html
Azder
1
OOP está identificando objetos en el sistema y construyendo clases basadas en esos objetos. No de la otra manera. Es por eso que también estoy en desacuerdo con "el enfoque de OOP es diseñar clases individuales y sus jerarquías".
Radu Murzea
1
Creo que esta es una pregunta muy subjetiva y está llena de suposiciones extrañas sobre la POO y sobre qué es el "mundo real" y cómo piensan las personas sobre los problemas. Y finalmente incluso pregunta "¿Y qué, si hay algo, se puede hacer para destronarlo?" lo que realmente muestra que el OP tiene una opinión muy fuerte al respecto. Si eres tan "religioso" acerca de los paradigmas de programación, supongo que no necesitas ninguna respuesta ... ya sabes lo que quieres escuchar. Si hubiera sabido sobre esta pregunta cuando se hizo por primera vez, probablemente habría votado para cerrarla ...
Simon Lehmann

Respuestas:

97

OOP no es natural para algunos problemas. Así es de procedimiento. Entonces es funcional. Creo que OOP tiene dos problemas que realmente lo hacen parecer difícil.

  1. Algunas personas actúan como si fuera la única forma verdadera de programar y todos los demás paradigmas están equivocados. En mi humilde opinión, todos deberían usar un lenguaje multiparadigma y elegir el mejor paradigma para el subproblema en el que están trabajando actualmente. Algunas partes de su código tendrán un estilo OO. Algunos serán funcionales. Algunos tendrán un estilo procesal directo. Con la experiencia se hace evidente qué paradigma es mejor para qué:

    a. OO es generalmente mejor para cuando tienes comportamientos que están fuertemente acoplados al estado en el que operan, y la naturaleza exacta del estado es un detalle de implementación, pero la existencia de este no puede ser fácilmente abstraída. Ejemplo: clases de colecciones.

    si. El procedimiento es mejor para cuando tienes un montón de comportamientos que no están fuertemente acoplados a ningún dato en particular. Por ejemplo, tal vez operan con tipos de datos primitivos. Aquí es más fácil pensar el comportamiento y los datos como entidades separadas. Ejemplo: código numérico.

    C. Funcional es mejor cuando tienes algo que es bastante fácil de escribir de manera declarativa, de modo que la existencia de cualquier estado es un detalle de implementación que se puede extraer fácilmente. Ejemplo: Mapa / Reducir paralelismo.

  2. OOP generalmente muestra su utilidad en grandes proyectos en los que es realmente necesario tener piezas de código bien encapsuladas. Esto no sucede demasiado en proyectos para principiantes.

dsimcha
fuente
44
Creo que un punto importante en la pregunta no era si la OOP es natural, sino si el enfoque principal de la OOP es el enfoque más natural. (Buena respuesta de todos modos.)
Giorgio
11
"OOP generalmente muestra su utilidad en proyectos grandes donde es realmente necesario tener piezas de código bien encapsuladas": pero esto no es una propiedad específica de OOP, ya que existen buenos conceptos de módulos también para lenguajes de programación imperativos, funcionales, ... .
Giorgio
2
OOP está realmente en un eje diferente al de procedimiento / funcional; aborda cómo organizar y encapsular el código, no cómo describir las operaciones. ( Siempre se asocia OOP con un paradigma de ejecución. Sí, hay lenguajes funcionales OOP +.)
Donal Fellows
1
¿No podría decirse que OOP son solo las cajas en las que ponemos los procedimientos?
Erik Reppen
En OOP, aún puedes escribir métodos. ¿Qué hace que la POO sea más débil que la programación de procedimientos?
Mert Akcakaya
48

En mi humilde opinión, es una cuestión de gusto personal y formas de pensar. No tengo mucho problema con OO.

Nosotros (o al menos yo) conceptualizamos el mundo en términos de relaciones entre las cosas que encontramos, pero el enfoque de OOP es diseñar clases individuales y sus jerarquías.

En mi humilde opinión esto no es así, aunque puede ser una percepción común. Alan Kay, el inventor del término OO, siempre enfatizó los mensajes enviados entre objetos, en lugar de los objetos en sí. Y los mensajes, al menos para mí, denotan relaciones.

Tenga en cuenta que, en la vida cotidiana, las relaciones y acciones existen principalmente entre objetos que habrían sido instancias de clases no relacionadas en OOP.

Si hay una relación entre los objetos, entonces están relacionados, por definición. En OO, podría expresarlo con una asociación / agregación / dependencia de uso entre dos clases.

Pensamos en términos de verbos bivalentes (a veces trivalentes, como, por ejemplo, en "Te di flores") donde el verbo es la acción (relación) que opera en dos objetos para producir algún resultado / acción. El foco está en la acción, y los dos (o tres) objetos [gramaticales] tienen la misma importancia.

Pero todavía tienen sus roles bien definidos en el contexto: sujeto, objeto, acción, etc. "Te di flores" o "Me diste flores" no son lo mismo (sin mencionar que "Flor te dio a mí": -)

Compare eso con OOP donde primero tiene que encontrar un objeto (sustantivo) y dígale que realice alguna acción sobre otro objeto. La forma de pensar cambia de acciones / verbos que operan con sustantivos a sustantivos que operan con sustantivos: es como si todo se dijera en voz pasiva o reflexiva, por ejemplo, "la ventana de terminal muestra el texto". O tal vez "el texto se dibuja en la ventana del terminal".

No estoy de acuerdo con esto. En mi humilde opinión, la oración en inglés "Bill, vete al infierno" se lee más naturalmente en el código del programa que en bill.moveTo(hell)lugar de move(bill, hell). Y el primero es, de hecho, más análogo a la voz activa original.

Por lo tanto, uno debe decidir si dirá terminalWindow.show (someText) o someText.show (terminalWindow)

Nuevamente, no es lo mismo pedirle al terminal que muestre algún texto, o pedirle al texto que muestre el terminal. En mi humilde opinión, es bastante obvio cuál es más natural.

Dados estos problemas, ¿cómo / por qué sucedió que la forma actual de hacer OOP se hizo tan popular?

¿Quizás porque la mayoría de los desarrolladores de OO ven a OO de manera diferente a usted?

Péter Török
fuente
15
+1 por mencionar directamente que los mensajes entre objetos y su importancia de Alan Kay
bunglestink
3
@zvrba, de hecho, también hubo otros pioneros de OO, pero eso no viene al caso en esta discusión. "Lo más natural es pedir que se muestre el texto". - ahora está utilizando la misma voz pasiva que afirmó que es tan "antinatural" en OOP.
Péter Török
55
@zvrba, usted dice 'siempre hay un "agente" [...] haciendo algunas cosas ", pero protesta contra el enfoque OO de identificar y nombrar a esos agentes (objetos) y manejarlos como ciudadanos de primera clase en el idioma . Para mí, esto es parte de modelar el dominio del problema: de todos modos, debe hacer ese trabajo, simplemente asignar el modelo de dominio resultante al código de una manera diferente, dependiendo de si su idioma es OO o no.
Péter Török
66
@zvrba, no es OO per se, sino un desarrollador / diseñador que decide sobre los roles y responsabilidades de los diferentes objetos. El uso del enfoque OO puede generar modelos y diseños de dominio buenos o malos, del mismo modo que usar un cuchillo puede obtener una rebanada de pan fino o un dedo sangrante, aún así no culpamos al cuchillo, porque es solo una herramienta. Tenga en cuenta también que los conceptos / objetos / agentes en el modelo son abstracciones de cosas en el mundo real y, como tales, siempre son limitadas y distorsionadas, centrándose únicamente en aspectos "interesantes" específicos.
Péter Török
66
@zvrba, un automóvil de hecho no arranca por su propia voluntad, tal como lo Carharía un objeto start()solo cuando alguien llama explícitamente a su método.
Péter Török
10

A algunos programadores les resulta difícil OOD porque a esos programadores les gusta pensar en cómo resolver el problema para la computadora, no en cómo se debe resolver el problema.

... pero el enfoque de OOP es diseñar clases individuales y sus jerarquías.

OOD NO se trata de eso. OOD se trata de descubrir cómo se comportan e interactúan las cosas.

Pensamos en términos de verbos bivalentes (a veces trivalentes, como, por ejemplo, en "Te di flores") donde el verbo es la acción (relación) que opera en dos objetos para producir algún resultado / acción. El foco está en la acción, y los dos (o tres) objetos [gramaticales] tienen la misma importancia.

El enfoque en OOD siempre está en la acción, donde las acciones son los comportamientos de los objetos. Los objetos no son nada sin sus comportamientos. La única restricción de objeto de OOD es que todo tiene que ser hecho por algo.

No veo al hacedor como más importante que la cosa que le hizo algo.

Pero, ¿por qué cargar a las personas con decisiones tan triviales sin consecuencias operativas cuando uno realmente quiere decir show (terminalWindow, someText)?

Para mí eso es lo mismo con una notación diferente. Todavía tiene que decidir quién es el espectador y quién es el espectador. Una vez que sabes eso, entonces no hay decisión en OOD. Windows muestra texto -> Window.Show (texto).

Muchas cosas (especialmente en el área heredada) dicen que está OO cuando no lo está. Por ejemplo, hay una gran cantidad de código C ++ que no implementa una figura de OOD.

OOD es fácil una vez que abandonas la mentalidad de que estás resolviendo un problema para las computadoras. Estás resolviendo problemas para cosas que hacen cosas.

Matt Ellen
fuente
10
No me gusta OOD exactamente porque prefiero pensar en cómo resolver el problema, punto. No quiero pensar en cómo traducir el lenguaje natural de un dominio problemático en un mundo extraño de objetos, mensajes, herencia, etc. No quiero inventar taxonomías jerárquicas donde no existen naturalmente. Quiero describir el problema en su lenguaje natural y resolverlo de la manera más fácil posible. Y, por cierto, el mundo no está hecho solo de "cosas que hacen cosas". Tu visión de la realidad es extremadamente estrecha.
SK-logic
77
@ Matt Ellen, escribo programas que modelan el comportamiento de las entidades que no son "cosas" y que no "hacen" ninguna "cosa". Cualquier entidad inmutable no hace nada. Cualquier función matemática pura no hace nada: es solo un mapeo de un conjunto a otro, y este mundo se describe principalmente por tales funciones. Cualquier formalismo lógico no "hace" nada. Sí, OOD no me ayudará, porque puedo usar abstracciones y modelos mucho más potentes. Volver a una OOD primitiva, limitada y limitante me perjudicará severamente.
SK-logic
2
@ Matt Ellen, sí, me gustaría ver referencias que respalden afirmaciones tan extrañas de que el mundo se ve mejor como una colección de "cosas que hacen cosas" u "objetos que interactúan a través de mensajes". Es completamente antinatural. Tome cualquier teoría científica (ya que todas están tan cerca de modelar el mundo real como es posible en esta etapa) e intente reescribirla usando su terminología. El resultado será torpe e incómodo.
SK-logic
44
@ Antonio2011a, no existe un único paradigma de programación o modelado que pueda cubrir todos los dominios posibles de problemas de manera eficiente. OOP, funcional, flujo de datos, lógica de primer orden, lo que sea, todos son paradigmas específicos del dominio del problema y nada más. Solo estoy abogando por la diversidad y el enfoque abierto para la resolución de problemas. Limitar su pensamiento a un solo paradigma es simplemente estúpido. Lo más parecido a un enfoque universal, que no lo limita a un solo marco semántico, es en.wikipedia.org/wiki/Language-oriented_programming
SK-logic
3
@ Calmarius, ¿por qué facilitarías la programación para las computadoras? Eso es una tontería. Son los humanos los que tienen que hacer el trabajo más duro.
Matt Ellen
7

Tal vez, no puedo entender el punto, pero:

Al leer el primer libro sobre OOP (principios de los 90, el delgado manual de Borland para Pascal), simplemente me sorprendió su simplicidad y potencial. (Antes, había estado usando Cobol, Fortran, lenguaje ensamblador y otras cosas prehistóricas).

Para mí, está bastante claro: un perro es un animal, un animal debe comer, mi perro es un perro, por lo que debe comer ...

Por otro lado, la programación en sí misma es inherentemente antinatural (es decir, artificial). El habla humana es artificial (no me culpes, todos hemos aprendido nuestros idiomas de otros, nadie conoce a la persona que inventó el inglés) también. Según algunos científicos, la mente humana está formada por el lenguaje que aprendió primero.

Admito que algunas construcciones en lenguajes OO modernos son un poco incómodas, pero es la evolución.

Nerevar
fuente
1
¿Cuál fue exactamente su trabajo para usted para pasar de cobol a fortran, luego al ensamblaje (y el resto)?
Grajo
1
Orden incorrecto. De hecho, comencé con Basic, luego me mudé a Fortran y luego a Assembly y Cobol (sí, es el orden correcto: primero Assembly). La primera computadora en mi vida fue una unidad central "gigantesca", 256kB de memoria, una máquina de escribir en su consola, alimentándola con tarjetas perforadas, porque yo era su operador. Cuando me había elevado lo suficiente como para convertirme en programador de sistemas, una cosa sospechosa llamada PC-AT había aterrizado en mi escritorio. Entonces me sumergí en GW-Basic, Turbo-Pascal, ... y así sucesivamente.
Nerevar
1
No me refería a eso. Más a su dominio de trabajo; porque no conozco a muchas personas (nadie realmente) que se ocupen de COBOL (orientado a los negocios), fortran (dominio científico), ensamblador (más orientado a cs) y luego esos otros. Sin embargo, sean programadores profesionales o no.
Torre
1
No es un misterio: unirse a equipos y proyectos donde antes se había tomado una decisión sobre el enfoque del lenguaje. Y cierto nivel de curiosidad no trivial sobre las herramientas que estaban utilizando.
Nerevar
6

Una cosa que me hizo difícil fue pensar que OOP se trataba de modelar el mundo. Pensé que si no lo entendía bien, algo podría venir y morderme el culo (algo es cierto o no). Era muy consciente de los problemas de fingir que todo es un objeto o entidad. Esto me hizo muy tentativo y poco seguro acerca de la programación en OOP.

Luego leí SICP y llegué a una nueva comprensión de que realmente se trataba de tipos de datos y de controlar el acceso a ellos. Todos los problemas que había desaparecido porque estaban basados ​​en una premisa falsa, que en OOP estás modelando el mundo.

Todavía me maravillo de la inmensa dificultad que me dio esta premisa falsa (y de cómo me dejo llevar por ella).

Pinochle
fuente
Gracias por señalar el peligro de intentar modelar el mundo.
Sean McMillan
4

Sí, la POO en sí misma es muy antinatural: el mundo real no está hecho completamente de taxonomías jerárquicas. Algunas pequeñas partes están hechas de esas cosas, y esas partes son las únicas cosas que podrían expresarse adecuadamente en términos de OO. Todo lo demás no puede encajar naturalmente en una forma de pensar tan trivial y limitada. Vea las ciencias naturales, vea cuántos lenguajes matemáticos diferentes se han inventado para expresar de la manera más simple o al menos comprensible la complejidad del mundo real. Y casi ninguno de ellos se puede traducir fácilmente a un lenguaje de objetos y mensajes.

SK-logic
fuente
55
Bueno, eso es igualmente cierto para cualquier tipo de notación formal que intente describir con precisión el mundo real.
Péter Török
1
@ Péter Török, precisamente mi punto. No existe un formalismo único que cubra todo. Tienes que usarlos todos, en toda su multitud aterradora. Y esa es la razón por la que creo en una programación orientada al lenguaje: permite adoptar varios formalismos, a menudo incompatibles, en una entidad de código sólida.
SK-logic
1
Todo se puede clasificar en taxonomías jerárquicas. El truco está en crear esquemas que tengan sentido. La herencia múltiple a menudo está involucrada. Una gran diferencia entre el software y el mundo real es que en el mundo real, a menudo tenemos que inferir o descubrir los esquemas de categorización; en software, los inventamos.
Caleb
1
Al usar un término como "taxonomía jerárquica", creo que estás pensando, bueno, en herencia. La herencia es realmente difícil de razonar. Es por eso que la gente sugiere usar la composición sobre la herencia.
Frank Shearar
1
@ Frank: Hay muchos tipos de taxonomías jerárquicas en el mundo real, de las cuales la herencia es solo una. Hacer todo esto correctamente requiere mejores herramientas que OOP (por ejemplo, razonamiento ontológico) y ha causado problemas a los filósofos durante milenios ...
Donal Fellows
4

Nosotros (o al menos yo) conceptualizamos el mundo en términos de relaciones entre las cosas que encontramos, pero el enfoque de OOP es diseñar clases individuales y sus jerarquías.

Estás comenzando (IMO) una premisa falsa. Las relaciones entre los objetos son posiblemente más importantes que los objetos mismos. Son las relaciones las que dan una estructura de programa orientada a objetos. La herencia, la relación entre clases, por supuesto es importante porque la clase de un objeto determina lo que ese objeto puede hacer. Pero son las relaciones entre objetos individuales las que determinan qué hace realmente un objeto dentro de los límites definidos por la clase y, por lo tanto, cómo se comporta el programa.

El paradigma orientado a objetos puede ser difícil al principio, no porque sea difícil pensar en nuevas categorías de objetos, sino porque es difícil imaginar un gráfico de objetos y comprender cuáles deberían ser las relaciones entre ellos, particularmente cuando no se tiene manera de describir esas relaciones. Es por eso que los patrones de diseño son tan útiles. Los patrones de diseño tratan casi por completo de las relaciones entre los objetos. Los patrones nos dan los componentes básicos que podemos usar para diseñar relaciones de objetos en un nivel superior y un lenguaje que podemos usar para describir esas relaciones.

Lo mismo es cierto en los campos creativos que funcionan en el mundo físico. Cualquiera podría juntar un montón de habitaciones y llamarlo un edificio. Las habitaciones pueden incluso estar completamente amuebladas con los últimos accesorios, pero eso no hace que el edificio funcione. El trabajo de un arquitecto es optimizar las relaciones entre esas habitaciones con respecto a los requisitos de las personas que utilizan esas habitaciones y el entorno del edificio. Lograr que esas relaciones sean correctas es lo que hace que un edificio funcione tanto desde una perspectiva funcional como estética.

Si tiene problemas para acostumbrarse a la POO, le animo a que piense más sobre cómo encajan sus objetos y cómo se organizan sus responsabilidades. Si aún no lo ha hecho, lea sobre los patrones de diseño: es probable que se dé cuenta de que ya ha visto los patrones sobre los que lee, pero darles nombres le permitirá ver no solo árboles, sino también rodales, matorrales, matorrales, bosques, arboledas, lotes de madera y eventualmente bosques.

Caleb
fuente
3

Esto es solo una parte de lo que está mal con OOP.

Esencialmente, las funciones se convierten en ciudadanos de segunda clase, y esto es malo.

Los lenguajes modernos (ruby / python) no sufren este problema y proporcionan funciones como objetos de primera clase, además de permitirle crear programas sin construir ninguna jerarquía de clases.

Hasen
fuente
OOP me parece muy natural, de hecho es difícil para mí pensar en programar tareas de otra manera. Aún así, a lo largo de los años he llegado a comprender que la POO tiende a enfatizar demasiado los sustantivos sobre los verbos. Esta diatriba de 2006 me ayudó a entender esta distinción: steve-yegge.blogspot.com/2006/03/…
Jim In Texas
3

OOP no es difícil. Lo que hace que sea difícil de usar bien es una comprensión superficial de lo que es bueno, donde los programadores escuchan máximas aleatorias y se las repiten en voz baja para recibir las bendiciones de la divina Banda de los Cuatro, el bendito Martin Fowler, o a quien más hayan estado leyendo.

Marcin
fuente
3

EDITADO

En primer lugar, me gustaría decir que nunca encontré OOP difícil, o más difícil que otros paradigmas de programación. La programación es inherentemente difícil porque trata de resolver problemas del mundo real y el mundo real es extremadamente complejo. Por otro lado, cuando leí esta pregunta me pregunté: ¿es la OOP "más natural" que otros paradigmas? ¿Y por lo tanto más efectivo?

Una vez encontré un artículo (ojalá pudiera encontrarlo nuevamente para poder publicarlo como referencia) sobre un estudio comparativo entre la programación imperativa (IP) y la programación orientada a objetos (OOP). Básicamente habían medido la productividad de los programadores profesionales que usan IP y OOP en diferentes proyectos, y el resultado fue que no habían visto grandes diferencias. Entonces, la afirmación era que no había una gran diferencia en la productividad entre los dos grupos, y que lo que realmente cuenta es la experiencia.

Por otro lado, los defensores de la orientación a objetos afirman que, si bien durante el desarrollo temprano de un sistema, la OOP puede tomar más tiempo que el imperativo, a la larga el código es más fácil de mantener y extender debido a la estrecha integración entre los datos y operaciones

He trabajado principalmente con lenguajes OOP (C ++, Java), pero a menudo tengo la sensación de que podría ser tan productivo con Pascal o Ada, aunque nunca los probé para proyectos grandes.

Compare eso con OOP donde primero tiene que encontrar un objeto (sustantivo) y dígale que realice alguna acción sobre otro objeto.

[cortar]

Por lo tanto, diría que la forma principal de hacer POO (basada en clases, despacho único) es difícil porque ES INNATURAL y no corresponde a cómo piensan los humanos sobre el mundo. Los métodos genéricos de CLOS están más cerca de mi forma de pensar, pero, por desgracia, este no es un enfoque generalizado.

Cuando leí este último párrafo con más cuidado, finalmente entendí el punto principal de su pregunta y tuve que volver a escribir mi respuesta desde cero. :-)

Conozco otras propuestas de OO en las que varios objetos reciben un mensaje en lugar de uno solo, es decir, varios objetos juegan un papel simétrico al recibir un mensaje. SÍ, esto me parece un enfoque OOP más general y quizás más natural (menos restrictivo).

Por otro lado, el "despacho múltiple" se puede simular fácilmente usando "despacho único" y el "despacho único" es más fácil de implementar. Tal vez esta sea una de las razones por las que el "despacho múltiple" no se ha convertido en la corriente principal.

Giorgio
fuente
3

Deja de buscar un paradigma exclusivo de OOP y prueba JavaScript.

Actualmente tengo algo de un esquema resuelto donde mis objetos de IU están operando bajo una interfaz controlada por eventos. Es decir, tendré lo que parece un método público típico que, cuando se dispara, da como resultado una acción definida internamente. Pero cuando se dispara, lo que realmente sucede es que disparo un evento en el objeto mismo y responde un controlador predefinido dentro de ese objeto. Cualquier evento que le interese escuchar puede escuchar este evento y el objeto de evento al que puede adjuntar propiedades que se pasa a cualquier otro oyente. Puede escuchar directamente al objeto, o puede escuchar generalmente ese tipo de evento (los eventos también se activan en un objeto genérico que todos los objetos construidos por la fábrica pueden escuchar). Entonces, por ejemplo, tengo un cuadro combinado en el que selecciona un nuevo elemento de la lista desplegable.

Si lo desea, (y me sorprendió descubrir que generalmente no quiero, es un problema de legibilidad cuando no puede ver de dónde proviene el evento), puede tener un desacoplamiento completo del objeto y establecer el contexto a través de un objeto de evento pasado. De todos modos, todavía está esquivando el envío único al poder registrar múltiples respondedores.

Pero no estoy haciendo esto solo con OOP y JS ni siquiera es "correctamente" OOP según algunas definiciones, lo que me parece gracioso. En mi opinión, lo apropiado para los niveles más altos de desarrollo de aplicaciones es tener el poder de doblar el paradigma a lo que funcione para su situación y podemos emular las clases perfectamente si lo queremos. Pero en este caso, estoy mezclando aspectos funcionales (pasando controladores) con OOP.

Más importante aún, lo que tengo se siente bastante poderoso. No estoy pensando en términos de un objeto que actúa sobre otro. Básicamente, estoy decidiendo qué les importa a los objetos, dándoles las herramientas que necesitan para ordenar las cosas y simplemente colocándolos en un mezclador y dejándolos reaccionar entre sí.

Así que supongo que lo que digo es esto: no es un problema de tipo declaración de cambio. Es mezclar y combinar. El problema son los idiomas y las modas que quieren que creas que es una cosa muy común. ¿Cómo puede un desarrollador Java junior, por ejemplo, apreciar realmente la POO cuando cree que siempre lo está haciendo correctamente de forma predeterminada?

Erik Reppen
fuente
2

La forma en que me lo explicaron fue con una tostadora y un automóvil. Ambos tienen resortes, por lo que tendrías un objeto "resorte" y tendrían diferentes tamaños, fortalezas y lo que sea, pero ambos serían "resortes" y luego extenderían esa metáfora en el auto, si tuvieras muchas ruedas (Ruedas, obviamente, más el volante, etc.) y eso tenía mucho sentido.

Luego puede pensar en el programa como una lista de objetos, y es mucho más simple visualizarlo que "Es una lista de cosas que hacen cosas, así que no es como esa lista de instrucciones que vio antes"

Creo que el verdadero problema con OOP es cómo se explica a las personas. A menudo (en mis clases uni) veo que se explica diciendo "se trata de muchas clases que hacen pequeñas cosas, y puedes crear objetos a partir de eso" y todo confunde a mucha gente, porque está usando lo que es esencialmente abstracto términos para explicar estos conceptos, en lugar de ideas concretas que las personas han captado cuando tenían 5 años jugando con lego.

Trezoide
fuente
2
Los resortes vienen en millones de formas, todas las cuales realizan funciones similares . Yo diría que este es un ejemplo perfecto para la programación funcional.
l0b0
2

Es la forma natural de pensar en el mundo a través de la categorización. De eso se trata más o menos OO. OOP es difícil porque la programación es difícil.

Tom Hawtin - tackline
fuente
Pero, ¿clasifica según si algunos objetos tienen atributos comunes o comportamientos comunes? ¿Es todo lo que tiene nombre y apellido una persona? ¿Todo lo que camina es un animal?
zvrba
Cuando se trata de categorización, ser capaz de realizar un determinado comportamiento es un atributo. Las cebras y los caballos pueden reproducirse, pero la descendencia es un híbrido. Es muy difícil predecir este resultado en función de poseer la función de apareamiento a menos que sepa que no son de la misma especie.
JeffO
1
@zvrba: Mi respuesta a la pregunta planteada en el comentario es esa it doesn't matter. Todo lo que tiene un nombre y un apellido es una persona para cada programa que solo se preocupa por las personas. Para cualquier programa que no tenga conocimiento de personas o no personas, es un IHasNameAndSurname. Los objetos solo necesitan resolver el problema en cuestión.
Tom W
@Jeff O Incluso dentro de la misma especie / raza / población hay variación y no hay un ejemplo ideal (esencial). Entonces, sí, OO no es como es realmente la naturaleza, pero se adapta bien a cómo los humanos piensan naturalmente.
Tom Hawtin - tackline
2

Creo que parte de la dificultad viene cuando las personas intentan usar OOP para representar la realidad. Todo el mundo sabe que un automóvil tiene cuatro ruedas y un motor. Todo el mundo sabe que los autos pueden Start(), Move()y SoundHorn().

Una luz se encendió en mi cabeza cuando me di cuenta de que debía dejar de intentar hacer esto todo el tiempo. Un objeto no es aquello con lo que comparte un nombre. Un objeto es (es decir, debería ser) una partición suficientemente detallada de datos relevantes para el alcance del problema. Es oughtde tener exactamente lo que la solución al problema que necesita tener, ni más ni menos. Si hacer que un objeto sea responsable de algún comportamiento da como resultado más líneas de código que el mismo comportamiento que es el trabajo de un tercero nebuloso (algunos podrían llamarlo 'poltergeist'), entonces el poltergeist gana sus chips.

Tom W
fuente
1

Para gestionar la complejidad, necesitamos agrupar la funcionalidad en módulos, y este es un problema difícil en general. Es como el viejo dicho sobre el capitalismo, OOP es el peor sistema para organizar el software, excepto por todo lo que hemos intentado.

La razón por la que agrupamos las interacciones dentro de los sustantivos, a pesar de que con frecuencia existe una ambigüedad sobre con cuál de los dos sustantivos se debe agrupar, es que la cantidad de sustantivos resulta en clases de tamaño manejable, mientras que la agrupación por verbos tiende a producir grupos muy pequeños, como los únicos, o grupos muy grandes para una función como show . Reutilizar conceptos como herencia también resulta mucho más fácil cuando se agrupa por sustantivos.

Además, la cuestión de decidir si poner show con la ventana o el texto es casi siempre mucho más clara en la práctica que en teoría. Por ejemplo, casi todos los grupos de kits de herramientas GUI se agregan con el contenedor, pero se muestran con el widget. Si intenta escribir código de la otra manera, la razón se hace evidente con bastante rapidez, a pesar de pensarlo de manera abstracta, los dos métodos parecen intercambiables.

Karl Bielefeldt
fuente
2
¿Alguna vez has visto un sistema de módulos adecuado ? ¿Cómo puedes decir que OOP es lo mejor disponible? Los módulos SML son mucho, mucho más potentes. Pero, incluso los paquetes Ada son suficientes para la mayoría de los casos, incluso sin un pequeño indicio de POO.
SK-logic
@ SK-logic, creo que te estás obsesionando con definiciones demasiado precisas. Por OOP, no me refiero a clases , me refiero a agrupar lógicamente "verbos" por los "sustantivos" en los que operan, y poder reutilizar y especializar esos verbos basados ​​en los sustantivos particulares en los que están operando. Las clases resultan ser la implementación más conocida de eso, pero no son la única implementación. Admito la ignorancia de los módulos SML, pero el primer ejemplo que vi cuando lo busqué fue una implementación de una cola que podría provenir de cualquier libro de diseño OO con cambios de sintaxis para que sea funcional.
Karl Bielefeldt
simplemente no sería justo darle demasiado crédito a una OOP desafortunada por algo que no le pertenece. Los módulos son un gran invento. Los módulos de primera clase son fantásticos. Pero OOP no tiene nada que ver con ellos en absoluto. Algunos lenguajes OOP adoptaron algunas de las características del módulo (más notablemente, espacios de nombres), pero los módulos son un concepto mucho más general y poderoso que las clases. Dijiste que las clases son "las mejores", lo que está lejos de ser verdad. Los módulos de primera clase son mucho mejores. Y, por supuesto, los sistemas de tipos son mucho más amplios y profundos que un simple OO con su subtipo.
SK-logic
1
"Es como el viejo dicho sobre el capitalismo, OOP es el peor sistema para organizar el software, excepto por todo lo que hemos intentado": tal vez no lo hemos intentado lo suficiente. :-)
Giorgio
1
Creo que significa 'democracia': quotationspage.com/quote/364.html
nicodemus13
1

No se . Hay varias formas de resolver un problema usando la programación: funcional, de procedimiento, lógica, OOP, otras.

En el mundo real, a veces, las personas usan el paradigma funcional, y a veces, nosotros usamos el paradigma procesal, y así sucesivamente. Y a veces nos confundimos. Y eventualmente los representamos como un estilo particular o paradigma de programación.

También existe el paradigma "todo es una lista o un elemento", utilizado en LISP. Me gusta mencionar como algo diferente de la programación funcional . PHP lo usa en matrices asociativas.

Los paradigmas OOP y "Todo es una lista o elemento" se consideran 2 de los estilos de programación MÁS NATURALES , como recuerdo en algunas clases de Inteligencia Artificial.

Me parece extraño, "OOP no es natural", tal vez la forma en que aprendes o la forma en que te han enseñado acerca de OOP es incorrecta, pero no la OOP en sí misma.

umlcat
fuente
1

Dados estos problemas, ¿cómo / por qué sucedió que la forma actual de hacer OOP se hizo tan popular? ¿Y qué, si hay algo, se puede hacer para destronarlo?

OOP se hizo popular porque ofrece herramientas para organizar su programa en un nivel de abstracción más alto que los populares lenguajes de procedimiento que lo precedieron. También fue relativamente fácil crear un lenguaje que tuviera una estructura procesal dentro de los métodos y una estructura orientada a objetos que los rodeara. Esto permitió a los programadores que ya sabían programar programar los principios OO uno por uno. Esto también condujo a muchos programas OO-in-name-only que eran programas procesales incluidos en una clase o dos.

Para destronar a OO, cree un lenguaje que facilite la transición incremental de lo que la mayoría de los programadores saben hoy (principalmente de procedimiento, con un poco de OO) a su paradigma preferido. Asegúrese de que proporcione API convenientes para realizar tareas comunes y promocionarlo bien. La gente pronto estará haciendo programas X-in-name-only en su idioma. Entonces puede esperar que pasen años y años para que las personas se vuelvan buenas haciendo X.

Sean McMillan
fuente
El OP no argumenta que OO es malo en general y debe ser destronado, sino que la "forma actual de hacer OOP" no es la más natural (en comparación con el "despacho múltiple").
Giorgio
OP también parece demasiado centrado en la definición de la jerarquía de tipos, donde los mejores programas de OO tienden a confiar más en las interfaces y la composición. Si el despacho múltiple es X, entonces la creación de un lenguaje que permita a las personas aprender gradualmente las habilidades asociadas con el despacho múltiple sigue siendo la clave para cambiar el entorno.
Sean McMillan
1

Creo que los idiomas OOP y OOP también tienen problemas.

Si lo entiende correctamente, OOP trata sobre cajas negras (objetos) que tienen botones que se pueden presionar (métodos). Las clases están ahí para ayudar a organizar estas cajas negras.

Un problema es cuando el programador coloca los botones en el objeto incorrecto. El terminal no puede mostrar texto en sí mismo, el texto no puede mostrarse en el terminal. El componente de administrador de ventanas del sistema operativo que puede hacer eso. La ventana de terminal y el texto son solo una entidad pasiva. Pero si pensamos de esta manera, nos damos cuenta de que la mayoría de las entidades son cosas pasivas y tendremos muy pocos objetos que realmente hagan algo (o simplemente uno: la computadora ). De hecho, cuando usa C, lo organiza en módulos, estos módulos representan pocos objetos.

Otro punto es que la computadora solo ejecuta instrucciones secuencialmente. Supongamos que tiene un VCRy un Televisionobjeto, ¿cómo reproduciría el video? Probablemente escribas algo como esto:

connect(television, vcr);
vcr.turnOn();
television.turnOn();
insert(vcr, yourFavoriteCasette);
vcr.play();
while (vcr.isPlaying()) {} // Wait while the VCR is playing the casette.
vcr.eject();
vcr.turnOff();
television.turnOff();

Esto sería así de simple, pero necesitaría al menos 3 procesadores ( o procesos ) para eso: uno desempeña el papel de usted, el segundo es el VCR, el tercero es el televisor. Pero normalmente solo tiene un núcleo (al menos no suficiente para todos sus objetos). En la universidad, muchos de mis compañeros de clase no entendían por qué la GUI se congela cuando un botón hace una operación costosa.

Así que creo que un diseño orientado a objetos puede describir el mundo bastante bien, pero no es la mejor abstracción para la computadora.

Calmarius
fuente
0

Eche un vistazo a DCI (datos, contexto e interacción) inventado por el inventor del patrón MVC.

El objetivo de DCI es (citado de Wikipedia):

  • Otorgue a la conducta del sistema un estado de primera clase, por encima de los objetos (sustantivos).
  • Separar limpiamente el código para cambiar rápidamente el comportamiento del sistema (lo que hace el sistema) del código para cambiar lentamente el conocimiento del dominio (lo que es el sistema), en lugar de combinar ambos en una interfaz de clase.
  • Para apoyar un estilo de pensamiento de objeto que esté cerca de los modelos mentales de las personas, en lugar del estilo de pensamiento de clase.

Aquí hay un buen artículo de los autores y aquí hay un pequeño ejemplo de implementación (.NET) si desea ver algún código. Es mucho más simple de lo que parece, y se siente muy natural.

Padre
fuente
0

A menudo se puede escuchar que OOP corresponde naturalmente a la forma en que las personas piensan sobre el mundo. Pero estaría totalmente en desacuerdo con esta declaración (...)

Como se evangeliza en libros y en otros lugares durante décadas, tampoco estoy de acuerdo con eso. Sin embargo, creo que Nygaard y Dahl fueron los que lo expresaron de esa manera, y creo que se estaban centrando en lo fácil que era pensar en diseñar simulaciones en comparación con las alternativas de la época.

(...) pero el enfoque de OOP es diseñar clases individuales y sus jerarquías.

Esta afirmación entra en un territorio sensible, dada la concepción errónea popular de OOP y cuán sensible es la OO a la definición. Tengo más de diez años en el campo, haciendo trabajo en la industria e investigación académica en prog. idiomas, y puedo decirles que pasé muchos años desaprendiendo "OO principal" porque comencé a notar cuán diferente (e inferior) es de lo que apuntaban los creadores anteriores. Para un tratamiento moderno y actualizado del tema, me referiría al esfuerzo reciente de W. Cook:

"Una propuesta para definiciones modernas y simplificadas de" objeto "y" orientado a objetos " http://wcook.blogspot.com.br/2012/07/proposal-for-simplified-modern.html

Dados estos problemas, ¿cómo / por qué sucedió que la forma actual de hacer OOP se hizo tan popular?

Tal vez la misma razón por la que los teclados QWERTY se hicieron populares o la misma razón por la que el sistema operativo DOS se hizo popular. Las cosas simplemente se llevan en vehículos populares, a pesar de sus propiedades, y se vuelven populares. Y a veces, las versiones similares pero peores de algo se consideran reales.

¿Y qué, si hay algo, se puede hacer para destronarlo?

Escribe un programa usando un enfoque superior. Escriba el mismo programa usando un enfoque OO. Mostrar que el primero tiene mejores propiedades que el segundo en todos los aspectos que son significativos (tanto las propiedades del sistema como las propiedades de ingeniería). Muestre que el programa elegido es relevante y el enfoque propuesto mantiene la alta calidad de las propiedades si se aplica a otros tipos de programas. Sea riguroso en su análisis y use definiciones precisas y aceptadas cuando sea necesario.

Finalmente, comparta sus hallazgos con nosotros.

Thiago Silva
fuente
-1

Tomemos Java: los objetos son una especie de cuello de botella de abstracción, la mayoría de las "cosas" son estrictamente subcomponentes de los objetos o usan objetos como sus subcomponentes. Los objetos deben ser lo suficientemente multipropósito como para una capa de abstracción completa entre estos dos tipos de cosas: el propósito múltiple significa que no hay una metáfora que encarnen. En particular, Java hace que los objetos (y clases) sean la única capa a través de la cual se llama / envía el código. Esta cantidad de cosas que los objetos encarnan los hace, francamente, demasiado complejos. Cualquier descripción útil de ellos debe restringirse a alguna forma especializada o restringida.

Las jerarquías de herencia e interfaz son "cosas" que usan objetos como subcomponentes. Esta es una forma especializada de describir objetos, no una forma de obtener una comprensión general de los objetos.

Se puede decir que los "objetos" tienen o son muchas cosas porque son una abstracción multipropósito que es más o menos universal en un "OO Langauge". Si se utilizan para contener un estado mutable local o para acceder a algún estado mundial externo, se parecen mucho a un "sustantivo".

Por el contrario, un objeto que representa un proceso, por ejemplo, "cifrar" o "comprimir" u "ordenar", parece un "verbo".

Algunos objetos se utilizan para su rol como espacio de nombres, por ejemplo, un lugar para colocar la función "estática" en Java.

Me inclino a estar de acuerdo con el argumento de que Java es demasiado pesado en las llamadas a métodos de objetos, con el despacho en el objeto. Esto probablemente se deba a que prefiero las clases de tipos de Haskell para controlar el despacho. Esta es una limitación de envío y es una característica de Java, pero no de la mayoría de los idiomas, o incluso de la mayoría de los idiomas OO.

Chris Kuklewicz
fuente
-3

He sido testigo y participé en muchos debates en línea sobre OOP. Los proponentes de OOP generalmente no saben cómo escribir el código de procedimiento adecuado. Es posible escribir código de procedimiento que sea altamente modular. Es posible separar el código y los datos y garantizar que las funciones solo puedan escribir en su propio almacén de datos. Es posible implementar el concepto de herencia usando código de procedimiento. Más importante aún, el código de procedimiento es más delgado, más rápido y más fácil de depurar.

Si crea módulos de un solo archivo con convenciones de nomenclatura estrictas, el código de procedimiento es más fácil de escribir y mantener que OO y hará lo mismo o más y más rápido. Y no olvide que cuando se ejecuta su aplicación, siempre es de procedimiento, sin importar cuántas clases tengan en su script.

Luego tiene el problema de los lenguajes como PHP, que no están realmente orientados a objetos y dependen de los hacks para falsificar cosas como la herencia múltiple. Los grandes personajes que influyen en la dirección del lenguaje han convertido PHP en un mosaico de reglas inconsistentes que se han vuelto demasiado grandes para lo que inicialmente pretendían. Cuando veo que los desarrolladores escriben grandes clases de plantillas para lo que se pensó como un lenguaje de plantillas de procedimiento, no puedo evitar sonreír.

Si compara el código OO escrito correctamente con el código de procedimiento mal escrito, siempre llegará a la conclusión incorrecta. Muy pocos proyectos justifican un diseño orientado a objetos. Si usted es IBM y administra un gran proyecto que varios desarrolladores deben mantener durante años, elija Orientado a objetos. Si está escribiendo un pequeño blog o sitio web de compras para un cliente, piénselo dos veces.

Para responder a la pregunta original, OOP es difícil porque no resuelve los dilemas de programación de la vida real sin recurrir a soluciones que son 100 veces más complicadas de lo que deberían ser. Una de las soluciones más poderosas para muchos problemas de programación es el uso juicioso de los datos globales. Sin embargo, los graduados universitarios de la nueva ola te dirán que es un gran no-no. Los datos disponibles a nivel mundial son peligrosos solo si eres un conejito de programación torpe. Si tiene un conjunto estricto de reglas y convenciones de nomenclatura adecuadas, puede salirse con la suya al tener todos sus datos globales.

Debería ser un requisito obligatorio para cualquier programador orientado a objetos saber cómo escribir una aplicación de juego de ajedrez en ensamblador para una memoria máxima disponible de 16K. Luego aprenderían a recortar la grasa, reducir la pereza y generar soluciones ingeniosas.

JG Estiot
fuente