¿Por qué es difícil la POO? [cerrado]

92

Cuando comencé a usar un lenguaje orientado a objetos (Java), prácticamente me fui "genial" y comencé a codificar. Nunca lo había pensado hasta hace poco después de haber leído muchas preguntas sobre la POO. La impresión general que tengo es que la gente lucha con eso. Como no lo he considerado tan difícil y no diría que soy un genio, creo que debo haberme perdido algo o haberlo entendido mal.

¿Por qué es difícil entender la POO? ¿ Es difícil de entender?

gablin
fuente
72
Contesto con: No es difícil de entender, solo difícil de dominar. La programación en su conjunto es de esta manera.
Steven Evers
2
umm, no lo es? ¿Quizás a los programadores que no pueden programar les resulta difícil culpar a los Uy en lugar de a sus líneas de código? No sé, pero nunca escuché a nadie decir que es difícil de entender. Sin embargo, he visto que ppl dice que funcional es extraño, especialmente porque no pueden cambiar el valor de su variable.
55
@ acidzombie42: funcional no es raro en absoluto. no tiene que escribir una lista de comandos para cambiar el contenido de las variables que representan una ubicación en la RAM. las variables representan valores, no cambias los valores; 42 permanece 42, x permanece x - lo que sea x. usted escribe funciones que se asignan desde sus parámetros a resultados. los valores son: números, listas de valores, funciones de valores a valores, programas que producen efectos secundarios y un valor resultante en la ejecución, y más. de esa manera, el compilador calculará el resultado de la función principal, es decir, el programa que se puede ejecutar.
comonad
55
He estado aprendiendo Haskell recientemente. Cuanto más aprendo y entiendo acerca de la programación funcional, más siento que la POO es difícil. Creo que la razón principal de esto es que OOP intenta unir los datos (objeto / clase) junto con la función que opera en ellos (método). Esta es la fuente del problema y muchos patrones de diseño de OOP están diseñados para evitar vincular datos y funciones. Ejemplo, el patrón de fábrica se usa para separar el constructor (que es una función) del objeto real en el que está operando.
ming_codes
1
Porque está mal nombrado. Realmente debería ser una programación orientada al sujeto, ya que el sujeto realiza la acción (verbo) y el objeto recibe la acción: John arrojó la pelota. Entonces johnsBall.throw () realmente no tiene sentido.
Chris Cudmore

Respuestas:

120

Personalmente, la mecánica de OOP me pareció bastante fácil de entender. La parte difícil para mí fue el "por qué". Cuando me expuse por primera vez, parecía una solución en busca de un problema. Aquí hay algunas razones por las que creo que a la mayoría de las personas les resulta difícil:

  1. En mi humilde opinión, enseñar OO desde el principio es una idea terrible. La codificación de procedimientos no es un "mal hábito" y es la herramienta adecuada para algunos trabajos. Los métodos individuales en un programa OO tienden a ser bastante procesales de todos modos. Además, antes de aprender la programación de procedimientos lo suficientemente bien como para que sus limitaciones se vuelvan visibles, OO no parece muy útil para el estudiante.

  2. Antes de que realmente pueda comprender OO, necesita conocer los conceptos básicos de las estructuras de datos y las funciones de enlace tardío / orden superior. Es difícil asimilar el polimorfismo (que básicamente pasa por un puntero a los datos y un montón de funciones que operan en los datos) si ni siquiera comprende los conceptos de estructurar datos en lugar de simplemente usar primitivas y pasar funciones de orden superior / punteros a funciones.

  3. Los patrones de diseño deben enseñarse como algo fundamental para OO, no como algo más avanzado. Los patrones de diseño te ayudan a ver el bosque a través de los árboles y te dan ejemplos relativamente concretos de dónde OO puede simplificar problemas reales, y de todos modos querrás aprenderlos eventualmente. Además, una vez que realmente obtienes OO, la mayoría de los patrones de diseño se vuelven obvios en retrospectiva.

dsimcha
fuente
55
respuesta fabulosa, especialmente el número 1. Por supuesto, los métodos en OO parecen métodos en un lenguaje de procedimiento, pero ahora están alojados en objetos que también tienen estado.
Dan Rosenstark
3
Me gustan especialmente tus primeros y terceros puntos. Mi amigo es gaga para los patrones de diseño, y sigo diciéndole que si solo usa una buena POO, la mayoría de ellos se derivan muy naturalmente del problema inicial.
CodexArcanum
77
+1 para "La parte difícil para mí fue el" por qué "". Lleva tiempo y esfuerzo comprender y aplicar los conceptos básicos del lenguaje (encapsulación) y los principios de diseño y los métodos de refactorización, hacia soluciones comunes (patrones de diseño).
Belun 01 de
12
Estoy de acuerdo con el n. ° 1, con la advertencia de que debe hacer un mejor trabajo para explicar OO a las personas que ya saben cómo programar de manera procesal que cuando estaba aprendiendo. No, no es útil ni informativo hablar sobre una Catclase que hereda Mammal, use un ejemplo real de un programa real que hubiéramos escrito procesalmente. Como una estructura de datos simple.
Carson63000
44
-1 Los patrones de diseño están tan enfatizados hoy en día. Son importantes, claro, pero: primero, son importantes para todos los paradigmas: funcionales, estructurados, así como OO; y segundo, no son parte del paradigma, solo un complemento conveniente que puede usar, como muchos otros. @SoftwareRockstar explica esto muy bien en su respuesta.
CesarGon
56

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 Dque herede de otro class Bsignifica que los objetos de class Dcompartir absolutamente, positivamente todas las características de class B. class Dpuede agregar características nuevas y diferentes, pero todas las características de class Bdeben 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:

  1. 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.
  2. Afirma que todos los autos tienen cuatro ruedas, y simplemente clasifica esos otros como "no autos" aunque sabemos que realmente lo son.
  3. 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).

Jerry Coffin
fuente
Muy bien dicho, y especialmente que la mayoría de los problemas con OOP que das no son solo problemas con principiantes que lo entienden, sino más bien problemas de OOP en general que la mayoría de los programadores de OOP aprenden a pensar. Últimamente he estado trabajando con el diseño de juegos en el que un modelo de componente funciona muy bien, que se correlaciona estrechamente con la noción de modelos relacionales en lugar de jerárquicos.
CodexArcanum
77
Je, estaba pensando en esto el otro día. Cómo todo el primer material de aprendizaje que leí en OOP parecía centrarse en la herencia, mientras que mi experiencia cada vez más me dice que la herencia es en su mayoría inútil si no dañina.
rmac el
Suena como la programación orientada a tablas , aunque diré que me doy cuenta de que OOP no es la bala de plata del desarrollo de software.
Onésimo Sin consolidar el
1
@OnesimusUnbound: la diferencia es que la programación genérica es una forma real y práctica de hacer algo, mientras que la programación orientada a la tabla es sobre todo la locura de un loco sobre una teoría sobre cómo algo podría funcionar (lea las publicaciones antiguas de TopMind en comp.object, y usted Veré a lo que me refiero: en realidad, es posible que las publicaciones no sean todas antiguas; por lo que sé, continúa hasta hoy).
Jerry Coffin
3
Es por eso que las interfaces son tan geniales. Usted toma el modelo de herencia y lo invierte a un enfoque de crianza primero. Por ejemplo, con el ejemplo del perro se puede suponer que cada perro tiene un género y hasta dos superespecies (una para cada padre) para una raza en particular. También puede haber una propiedad de lista que contenga rasgos, pero la variedad posible hace que no tenga sentido calzarlos en una estructura definida. Es mejor implementar una búsqueda profunda para rastrear los rasgos y combinar razas similares basadas en esos resultados.
Evan Plaice
26

OOP requiere la capacidad de pensar de manera abstracta; un regalo / maldición que pocas personas, incluso los programadores profesionales, realmente tienen.

John Kraft
fuente
35
Toda la programación es abstracta.
JeffO
28
@ Jeff O - No estoy de acuerdo. La programación solo requiere la capacidad de decirle a alguien cómo hacer algo paso a paso. Si puede decirle a alguien cómo hacer un sándwich de mantequilla de maní y mermelada, tiene la capacidad de escribir comandos en una interfaz de programación. Ese es un conjunto de habilidades completamente diferente al modelado abstracto de sándwich ap, b & j y cómo interactúa con el mundo.
John Kraft
16
Darle a alguien 2 lápices y luego entregarles 1 lápiz y preguntar cuántos lápices tienen, es concreto. 2 + 1 = 3 es abstracto.
JeffO
17
Estoy de acuerdo con Jeff La programación básicamente es manejar abstracciones. Al menos eso es cierto para cualquier cosa que no sea el flujo de programa más básico (porque todo lo demás será demasiado complejo sin abstracciones). Hay una fase distinta en aprender a programar cuando el novato aprende a controlar las abstracciones. Ahí es donde cae la metáfora de la receta. La programación no es como cocinar y, si bien un algoritmo individual puede compararse con una receta, la programación es fundamentalmente diferente de la implementación de algoritmos aislados.
Konrad Rudolph el
2
@KonradRudolph Gran punto. +1 para "Todo lo demás será demasiado complejo sin abstracciones" .
Karthik Sreenivasan
21

Creo que puedes resumir la dificultad básica de esta manera:

// The way most people think.
Operation - object - parameters
// Example:
Turn the car left.

// The way OOP works conceptually
Object - operation - parameters
// Example:
Car.Turn(270);

Claro, la gente puede acostumbrarse al mapeo de "izquierda" como 270, y sí, decir "Car.Turn" en lugar de "turn the car" no es un gran salto. PERO, para tratar bien con estos objetos y crearlos, debe invertir la forma en que normalmente piensa.

En lugar de manipular un objeto, le estamos diciendo al objeto que haga cosas por sí mismo. Puede que ya no parezca difícil, pero decirle a una ventana que se abra parece extraño. Las personas que no están acostumbradas a esta forma de pensar tienen que luchar con esa rareza una y otra vez hasta que finalmente se vuelve natural.

John Fisher
fuente
77
Buena idea Creo que el problema es que en la vida real, no hay mucho que pueda hacer un "objeto" que no esté relacionado con otros objetos. OO funciona bien en la medida en que se les dice a los objetos que modifiquen su estado interno: rectangle.enlarge (margin_in_pixels) pero me di cuenta de los límites hace años. Un día los programadores estábamos instalando hardware. Alguien se burló de "tornillo. Gire" Es curioso, pero me hizo pensar: claro, un tornillo puede cambiar su orientación, pero en realidad es una operación entre el gabinete y el tornillo; ninguno de los objetos puede hacer la tarea por sí mismo. OO simplemente no es lo suficientemente bueno.
DarenW
3
+1, después de años de escribir "substr (fecha, 0,4)", es difícil escribir "date.substring (0,4)"
ern0
44
+1 para el fragmento de código. Representa claramente un proceso de pensamiento real.
Karthik Sreenivasan
2
Realmente lo leería como un comando que envías. Como en "dile al auto que gire a la izquierda". Oop se basó en enviar mensajes a objetos, así que así es como lo interpretaría.
bunglestink
1
Buena idea, ¿entonces OOP puede ser más adecuado para modelar "sistemas de agentes"?
Qbik
21

Cualquier paradigma requiere un cierto empuje "al límite" para comprender, para la mayoría de las personas. Por definición, es un nuevo modo de pensamiento y, por lo tanto, requiere una cierta cantidad de abandono de viejas nociones y una cierta cantidad de comprensión total de por qué las nuevas nociones son útiles.

Creo que gran parte del problema es que los métodos utilizados para enseñar la programación de computadoras son bastante pobres en general. OOP es tan común ahora que no es tan notable, pero aún lo ves a menudo en la programación funcional:

  • conceptos importantes están ocultos detrás de nombres extraños (FP: ¿Qué es una mónada? OOP: ¿Por qué los llaman funciones a veces y métodos otras veces?)

  • los conceptos extraños se explican en metáfora en lugar de en términos de lo que realmente hacen, o por qué los usarías, o por qué alguien alguna vez pensó en usarlos (FP: Una mónada es un traje espacial, envuelve un código. OOP: Un El objeto es como un pato, puede hacer ruido, caminar y hereda de Animal)

  • lo bueno varía de persona a persona, por lo que no está del todo claro cuál será el punto de inflexión para cualquier estudiante, y a menudo el maestro ni siquiera puede recordarlo. (FP: Oh, las mónadas te permiten ocultar algo en el tipo en sí mismo y continuar sin tener que escribir explícitamente lo que sucede cada vez. OOP: Oh, los objetos te permiten mantener las funciones para un tipo de datos con esos datos).

Lo peor de todo es que, como indica la pregunta, algunas personas entenderán de inmediato por qué el concepto es bueno, y otras no. Realmente depende de cuál es el punto de inflexión. Para mí, comprender que los objetos almacenan datos y métodos para esos datos fue la clave, después de eso, todo lo demás encaja como una extensión natural. Luego tuve saltos posteriores como darme cuenta de que una llamada a un método desde un objeto es muy similar a hacer una llamada estática con ese objeto como primer parámetro.

Los pequeños saltos posteriores ayudan a refinar la comprensión, pero es el primero que saca a una persona de "OOP no tiene sentido, ¿por qué la gente hace esto?" a "OOP es lo mejor, ¿por qué la gente hace algo más?"

CodexArcanum
fuente
8
Particularmente odio el metaforismo, la mayoría de las veces, confunden en lugar de describir.
Lie Ryan
3
"Luego tuve saltos posteriores como darme cuenta de que una llamada a un método desde un objeto es muy similar a hacer una llamada estática con ese objeto como primer parámetro". Desearía que esto se enfatizara más desde el principio, ya que está en lenguajes como Python.
Jared Updike
1
Mi problema con el uso de metáforas para explicar conceptos es que el maestro a menudo se detiene en la metáfora, como si eso explicara todo. No, eso no es una explicación completa; eso es solo una ilustración para ayudarnos a entender la explicación real .
jhocking
¡Gran respuesta! +1 por explicar que el primer paso para comprender la POO será más significativo que lo que viene después como extensiones naturales con una buena comprensión de la base. : D
Karthik Sreenivasan
Lo mismo ocurre con el aprendizaje "salto": cuando comencé a percibir la POO como una construcción "meramente" modular / estructurada / escalonada, pero con esteroides; cuando reescribí algunos programas COBOL muy viejos y destrozados. A pesar del alcance global de COBOL, esencialmente había aplicado los principios de OO con estructuras de registro personalizadas, variables de un solo propósito y párrafos (métodos) modulares y estructurados muy enfocados.
radarbob
15

Porque la explicación básica de OOP tiene muy, muy poco que ver con cómo se usa en el campo. La mayoría de los programas para enseñarlo intentan usar un modelo físico, como "Piense en un automóvil como un objeto, y las ruedas como objetos, y las puertas y la transmisión ...", pero fuera de algunos casos oscuros de programación de simulación, los objetos se usan mucho más a menudo para representar conceptos no físicos o para introducir indirección. El efecto es que hace que las personas lo entiendan intuitivamente de manera incorrecta.

Enseñar a partir de patrones de diseño es una forma mucho mejor de describir OOP, ya que muestra a los programadores cómo algunos problemas reales de modelado pueden atacarse efectivamente con objetos, en lugar de describirlo en abstracto.

Dan Monego
fuente
13

No estoy de acuerdo con la respuesta de dsimcha en su mayor parte:

  1. Enseñar OO desde el principio no es realmente una mala idea en sí misma, ni tampoco lo es enseñar lenguajes de procedimiento. Lo importante es que enseñamos a las personas a escribir código claro, conciso y coherente, independientemente de OO o de procedimiento.

  2. Los métodos individuales en buenos programas de OO NO tienden a ser de procedimiento en absoluto. Esto se está volviendo cada vez más cierto con la evolución de los lenguajes OO (lea C # porque aparte de C ++ es el único otro lenguaje OO que conozco) y su sintaxis que se vuelve más compleja cada día (lambdas, LINQ a objetos, etc.). La única similitud entre los métodos y procedimientos de OO en los lenguajes de procedimiento es la naturaleza lineal de cada uno, que dudo que cambie pronto.

  3. No puede dominar un lenguaje de procedimiento sin comprender tampoco las estructuras de datos. El concepto de puntero es tan importante para los lenguajes de procedimiento como para los lenguajes OO. Pasar parámetros por referencia, por ejemplo, que es bastante común en los lenguajes de procedimiento, requiere que comprenda los punteros tanto como se requiere para aprender cualquier lenguaje OO.

  4. No creo que los patrones de diseño deban enseñarse temprano en la programación OO, porque no son fundamentales para la programación OO. Definitivamente, uno puede ser un buen programador de OO sin saber nada sobre patrones de diseño. De hecho, una persona puede incluso usar patrones de diseño conocidos sin siquiera saber que están documentados como tales con nombres propios y que se escriben libros sobre ellos. Lo que se debe enseñar fundamentalmente son los principios de diseño, como la responsabilidad única, el cierre abierto y la segregación de interfaz. Desafortunadamente, muchas personas que se consideran programadores de OO en estos días no están familiarizados con este concepto fundamental o simplemente eligen ignorarlo y es por eso que tenemos tanto código OO basura por ahí.

Para responder la pregunta original del cartel, sí, OO es un concepto más difícil de entender que la programación de procedimientos. Esto se debe a que no pensamos en términos de propiedades y métodos de los objetos de la vida real. Por ejemplo, el cerebro humano no piensa fácilmente en "Encender" como un método de televisión, sino que lo ve como una función del encendido humano de la televisión. Del mismo modo, el polimorfismo es un concepto extraño para un cerebro humano que generalmente ve cada objeto de la vida real con una sola "cara". La herencia nuevamente no es natural para nuestros cerebros. El hecho de que sea desarrollador no significa que mi hijo sea uno. En términos generales, el cerebro humano necesita ser entrenado para aprender OO mientras que los lenguajes de procedimiento son más naturales.

SoftwareRockstar
fuente
2
+1 - Yo tampoco creo que los patrones de diseño sean necesarios para la enseñanza de OOP en el nivel fundamental, puedes ser un buen programador de OOP y no conocer ningún patrón de diseño. Por otro lado, tiende a ver que los patrones de diseño conocidos surgen naturalmente de los buenos programadores de OOP. Los patrones de diseño siempre se descubren, no se inventan.
Gary Willoughby
1
+1 - Gran respuesta. Me gusta el cuarto punto que has dicho. ¡Es muy cierto que uno puede ser un buen programador de OO sin saber qué son realmente los patrones de diseño!
Karthik Sreenivasan
Estoy de acuerdo con el n. ° 4 porque la mayoría de los patrones de diseño no son más que un enfoque de goma de mascar / cinta adhesiva para codificar expresamente en torno a las limitaciones del lenguaje. En otros paradigmas, los patrones de diseño pueden ser completamente diferentes y estar basados ​​en sus propias restricciones. No estoy de acuerdo con 2, LINQ y lambdas todavía se ejecutan de manera procesal, solo proporcionan abstracciones de alto nivel perfectamente empaquetadas. Dedique un tiempo significativo a desarrollar con un lenguaje de procedimiento / funcional de tipo dinámico como JavaScript y verá lo que quiero decir.
Evan Plaice
6

Creo que muchos programadores tienen dificultades con el diseño inicial y la planificación para comenzar. Incluso si alguien hace todo el diseño por usted, aún es posible romper con los principios de OOP. Si tomo un montón de código de spaghetti y lo vuelvo a una clase, ¿eso es realmente POO? Alguien que no entiende OOP todavía puede programar en Java. Además, no confunda la dificultad de comprender con no estar dispuesto a seguir una determinada metodología o estar en desacuerdo con ella.

JeffO
fuente
5

Deberías leer Objetos Nunca? Bueno, casi nunca. (Se requiere membresía de ACM) por Mordechai Ben-Ari, quien sugiere que OOP es tan difícil, porque no es un paradigma que sea realmente natural para modelar cualquier cosa. (Aunque tengo reservas sobre el artículo, porque no está claro qué criterios cree que un programa debe cumplir para decir que está escrito en el paradigma OOP en lugar de un paradigma de procedimiento que usa un lenguaje OO).

Ken Bloom
fuente
5

La programación orientada a objetos en sí misma no es difícil.

Lo difícil es hacerlo bien. ¿Dónde colocar el corte entre el código para que pueda mover fácilmente las cosas al objeto base común y extenderlas más tarde? Cómo hacer que otros usuarios puedan usar su código (ampliar clases, envolver proxies, método de anulación) sin saltar a través de los aros para hacerlo.

Esa es la parte difícil, y si se hace bien puede ser muy elegante, y si se hace mal puede ser muy torpe. Mi experiencia personal es que requiere mucha práctica haber estado en todas las situaciones en las que DESEAS haberlo hecho de manera diferente, para hacerlo bien esta vez.

usuario1249
fuente
"Mi experiencia personal es que requiere mucha práctica haber estado en todas las situaciones en las que DESEAS haberlo hecho de manera diferente, para hacerlo bien esta vez". OOP parece una lista codificada de formas de no hacerlo mal, lo cual no tiene sentido hasta que lo hayas hecho mal en todas esas formas.
Jared Updike
@Jared, no del todo. Compárelo con la solución de sodukus. Hay varios trucos que puedes hacer para resolverlo, pero lleva tiempo y práctica hacerlo bien sin retroceder.
Si uno piensa en un "objeto base común" como un antepasado común, entonces queda claro. Es realmente así de simple. Es difícil de entender porque hay muchas explicaciones engañosas de personas que intentan parecer inteligentes.
annoying_squid
4

Estaba viendo un video de Richard Feynman sobre cómo las personas pueden tener metodologías completamente diferentes cuando piensan, quiero decir, completamente diferente.

Cuando hago un diseño de alto nivel, visualizo objetos, puedo verlos, ver sus interfaces y ver qué rutas necesita atravesar la información.

También tengo problemas para recordar detalles y descubrí que OO es una gran ayuda para la organización, mucho más fácil de encontrar funcionalidad que escanear a través de una lista de subrutinas poco organizada.

Para mí, OO fue un gran beneficio, pero si no visualizas de la misma manera o no haces una arquitectura de alto nivel, probablemente sea inútil y molesto.

Bill K
fuente
+1 Siento lo mismo, pero hay muchos empujones en la dirección opuesta, incluidos los mixins de Ruby ... lo que te hace darte cuenta de que el estricto OO no es para todos.
Dan Rosenstark
@Yar Sí, eso es más o menos lo que estaba diciendo. Aunque personalmente no puedo imaginar nada mejor (y Ruby me dio NUTS por el año que lo usé), estoy empezando a aceptar que todos tienen una forma diferente de verlo. Quizás algunas personas usan el tacto o el oído cuando piensan en lugar de visualizar y OO simplemente no les ayuda.
Bill K
Creo que también ayuda a fomentar convenciones de nomenclatura más naturales. Ya no necesita codificar el tipo de una función en el nombre de la función (como INSTR), porque el nombre se adjunta al tipo (como string::find)
Ken Bloom
@Ken, aunque estoy de acuerdo, creo que es más una cuestión de tipeo fuerte que OO: Ruby tiene OO, pero se pierde mucha información de tipo debido a la escritura de patos. Ruby tiende a decir "enviarlo" y esperar para saber qué método mágico "it" tiene que implementar para que funcione.
Bill K
@Bill, tienes razón. Es más una cuestión de lenguajes que admiten programación genérica. Puede obtener buenas convenciones de nomenclatura natural con sistemas de módulos y clases de tipos como Haskell's, y no hay nada de extraño en Haskell. Si C tuviera una sobrecarga, podría obtener los mismos tipos de nombres genéricos en C.
Ken Bloom
4

Que había hecho GW-Basic y Turbo Pascal programar un poco justo antes de ser introducido a OO, por lo que inicialmente se DID hacer en mi cabeza.

No tengo idea si esto es lo que les sucede a otros, pero para mí fue así: mi proceso de pensamiento sobre la programación fue puramente de procedimiento. Como en: "tal y tal sucede, entonces tal y tal sucede después", etc. Nunca consideré que las variables y los datos fueran algo más que actores fugaces en el flujo del programa. La programación era "el flujo de acciones".

Supongo que lo que no fue fácil de entender (por estúpido que me parezca ahora), fue la idea de que los datos / variables realmente importan , en un sentido más profundo que simplemente ser actores fugaces en el "flujo" del programa. O para decirlo de otra manera: seguí tratando de entenderlo a través de lo que sucede , en lugar de a través de lo que es , que es la verdadera clave para comprenderlo.

Bobby Tables
fuente
Interesante punto de vista. Mientras lucho por dar sentido a un proyecto masivo de C ++, creo que soy todo lo contrario, pensando principalmente en términos de datos, la "ruta de señal" de bits desde alguna "entrada" a alguna "salida". Si bien yo también hice mucho Basic y Pascal, mi primer pensamiento técnico fue en electrónica.
DarenW
3

No creo que sea difícil de entender, pero puede ser que muchos de los programadores que realizan consultas sean nuevos en el concepto, provenientes de lenguajes de procedimiento.

Por lo que he visto / leído, mucha gente (al menos en los foros) busca un 'resultado' de OOP. Si usted es un programador de procedimientos que no retrocede y modifica el código extendido, probablemente sea difícil entender los beneficios.

Además, hay una gran cantidad de POO por ahí, si las personas leen o ven eso, entonces es fácil ver por qué les puede resultar difícil.

En mi opinión, debes esperar hasta que haga clic o alguien que tenga conocimientos reales, no creo que puedas apresurarte.

DBlackborough
fuente
55
Si vienes de un entorno académico, los tipos de programas de juguetes que escribes allí también parecen realmente inútiles en OOP. Comencé a aprender C en la universidad, y eso fue bastante fácil de entender porque cada programa tenía 1 página, menos de 100 líneas. Luego intenta aprender OOP y requiere todo este equipaje y sobrecarga de objetos solo para hacer lo mismo, y parece inútil. Pero hasta que haya escrito un programa en muchos archivos y unas pocas miles de líneas, es difícil ver por qué cualquier estilo de programación es útil.
CodexArcanum
3

Creo que la razón por la que OOP es difícil para muchos es porque las herramientas realmente no lo facilitan.

Los lenguajes informáticos actuales son una abstracción de lo que sucede en la computadora.

OOP es una forma abstracta de representar abstracciones.

Entonces estamos usando una abstracción para construir abstracciones con una abstracción. Agregue a esto que lo que estamos abstrayendo generalmente son interacciones físicas / sociales muy complejas y, bueno, no es de extrañar.

ElGringoGrande
fuente
2

De hecho, tengo un blog llamado "Luchas en la programación orientada a objetos", que surgió de algunas de mis dificultades para aprenderlo. Creo que fue particularmente difícil para mí entender porque pasé mucho tiempo usando la programación de procedimientos, y tuve dificultades para entender la idea de que un objeto podría ser representado por una colección de atributos y comportamientos (estaba acostumbrado a simplemente una colección de variables y métodos).

Además, hay muchos conceptos que hacen que un lenguaje esté orientado a objetos: herencia, interfaces, polimorfismo, composición, etc. Realmente hay mucho que aprender sobre su teoría antes de que realmente pueda escribir código de manera efectiva, y en una orientación a objetos. de manera que, mientras que con la programación de procedimientos, es simplemente una cuestión de entender cosas como la asignación de memoria para variables y llamadas de puntos de entrada a otros métodos.

Tim Claason
fuente
De acuerdo: muchas de las dificultades que las personas tienen con OO es que se han entrenado para pensar 'procedimentalmente'. No hay nada intrínsecamente difícil en OO, pero si 'conoce' las técnicas de procedimiento, sería una gran sorpresa ver otra forma de estructurar las cosas.
Kirk Broadhurst
Sin duda, es una forma de pensar completamente diferente de la programación procesal. Pero al contrario de lo que muchos dicen, no es A) una forma de pensar antinatural, y B) complicada. Solo creo que no se enseña bien.
annoying_squid
2

Motivación. Es más difícil aprender algo cuando no ves por qué, y también cuando no puedes ver lo que hiciste y descubrir si lo hiciste bien o no.

Lo que se necesita son pequeños proyectos que usen OO para hacer cosas útiles. Sugeriría mirar un libro sobre patrones de diseño y encontrar uno que sea obviamente útil y que funcione bien con OO. (Usé Estrategia la única vez que lo probé. Algo como Flyweight o Singleton serían malas elecciones, ya que son formas de usar objetos en general, no usar objetos para lograr algo).

David Thornley
fuente
La gente siempre habla sobre Singleton, pero siempre está invitado a la fiesta. Pero es cierto, él es el no-OO OO DP.
Dan Rosenstark
-1

Creo que depende de la edad (edad como representante de la experiencia) y, lo que es más importante, del interés. Si eres "joven" (es decir, verde, tal vez) y nunca has pensado de otra manera, parece bastante sencillo. Por otro lado, si crees que es lo mejor que has visto, me pasó a los 28 años o algo así, es fácil de asimilar.

Por otro lado, si piensas, como lo hicieron muchos de mis estudiantes de Java, "por qué estamos aprendiendo esto, es solo una moda pasajera", es prácticamente imposible de aprender. Esto es cierto con la mayoría de las tecnologías.

Yar
fuente
1
OO una moda pasajera? ¿Cuántos años tienen sus estudiantes? Sospecho que esta "moda" es mayor que ellos (la primera vez que lo hice, que sabía que tenía, era Simula en 1983/4 y Simula no era nueva en ese momento)
Murph
@Murph Esto fue aproximadamente en 2004-2005 y los estudiantes tenían definitivamente más de 45-50 (programadores profesionales en Iberia).
Dan Rosenstark
ok, puedo ver cómo podrían haberse perdido el comienzo de la OO. Pero en 2004/5 estábamos bien en .NET, que es prácticamente de pared a pared OO (-: Hay cosas en el desarrollo que uno podría describir como modas, pero las que no fracasan rápidamente tienden a evolucionar en cosas buenas
Murph
1
@Murph para ser honesto, estos muchachos eran programadores de mainframe que intentaban convertir a Java. En realidad, fue una experiencia divertida y única (no es una tarifa normal para mis días de Java Trainer). Que es cierto, sin embargo, que habían visto muchas cosas van y vienen, pero obviamente OO es más que una moda. En una nota aparte: esperaba que esta prueba de Unidad se volviera loca, pero ahora descubro que tengo muchas pruebas de unidad para escribir ... :)
Dan Rosenstark
-1

Independientemente del paradigma (POO, funcional, etc.) que elija, para escribir un programa de computadora, necesita saber qué pasos hará su programa.

La forma natural de definir un proceso es escribir sus pasos, para tareas más grandes, divide la tarea en pasos más pequeños. Esta es la forma de procedimiento, así es como funciona la computadora, así es como se va a través de su lista de verificación paso a paso.

OOP es una forma diferente de pensar. En lugar de pensar en una lista de tareas que debe hacerse paso a paso, piensa en los objetos, sus habilidades y relaciones. Entonces escribirás muchos objetos, pequeños métodos y tu programa funcionará mágicamente. Para lograr esto, debes torcer tu mente ...

Y es por eso que OOP es difícil. Como todo es un objeto, todo lo que hacen es pedirle a otros objetos que hagan algo, y esos otros objetos básicamente hacen algo. Por lo tanto, el control en un programa OOP puede saltar de un lado a otro entre los objetos.

Calmarius
fuente
-1

Como alguien que actualmente está aprendiendo programación y tiene algunos problemas en esta área, no creo que sea tanto que el concepto sea difícil de entender como lo son las implementaciones específicas de dicho concepto. Digo esto porque tengo la idea de OOP, y la he usado en PHP durante aproximadamente un año, pero a medida que avanzo a C # y miro el uso de objetos de otros programadores, encuentro que muchas personas lo hacen de maneras que simplemente no entiendo Esto es específicamente lo que me ha llevado a encontrar un mejor entendimiento de los principios de la POO.

Por supuesto, me doy cuenta de que el problema es probablemente mi falta de experiencia con un lenguaje nativo de OOP, y que a medida que pase el tiempo encontraré nuevas formas de utilizar objetos que serán tan poco claros para un nuevo programador como lo que soy. Actualmente experimentando. Jerry Coffin toca esto varias veces, particularmente en su comentario:

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.

Creo que esto es muy preciso, ya que es la impresión que a menudo tengo cuando veo a alguien creando clases para cosas que no son realmente cosas; se me escapa un ejemplo específico, pero lo más cercano que puedo encontrar sobre la marcha es tratar la distancia como un objeto (editaré la próxima vez que vea algo que cause esta misma confusión). A veces, OOP parece ignorar temporalmente sus propias reglas y se vuelve menos intuitivo. Esto ocurre con mayor frecuencia cuando los objetos producen objetos, heredan de una clase que los encapsula, etc.

Creo que para alguien como yo, es útil pensar que el concepto de objetos tiene múltiples facetas, una de las cuales incluye tratar algo como un objeto cuando de otro modo no lo sería. Algo así como la distancia, con solo un pequeño cambio de paradigma, podría aparecer como un objeto teórico, pero no uno que pudiera sostenerse en la mano. Tengo que pensar que tiene un conjunto de propiedades pero un conjunto más abstracto de comportamientos, como acceder a sus propiedades. No estoy seguro de que esta sea la clave para mi comprensión, pero parece ser a donde conducen mis estudios actuales.

revs dsimer
fuente
1
Un par de puntos u objetos deben considerarse como un objeto. Y la distancia debe tomarse como una función del objeto. Usar objetos no significa que hagas objetos a partir de todo.
Gangnus
Como dije, la distancia era un mal ejemplo. En cuanto a hacer un objeto a partir de todo, me refiero específicamente a lo que he visto que ocurre, no a lo que realmente he hecho, que todavía no es nada.
dsimer
Depende del idioma: en SmallTalk la distancia (y todo) ES un objeto. Pero en C # has mencionado que sería malo.
Gangnus
-2

Las terminologías fueron mi obstáculo en el camino cuando aprendí los principios de la programación orientada a objetos (POOP). Es cuando entiendes los fundamentos que las piezas comienzan a encajar. Al igual que todas las cosas, aprender nuevos conceptos es un poco difícil.

Acordó que los patrones de diseño deberían ser pensados ​​al menos paralelos a OOP.

señor-fu
fuente
-2

El salto principal para mí fue entender el concepto abstracto de OOP. Ahora que soy muy nuevo en la programación en general, he estado programando durante un año a un año y medio, así que mi introducción en OOP fue con Actionscript y Processing. Cuando aprendí por primera vez la codificación Actionscript, no estaba en OOP. Aprendí a codificar directamente en el panel Acciones y así aprendí los fundamentos básicos de la programación (variables, funciones, bucles, etc.). Entonces lo aprendí como hacer algo directamente en el escenario en Flash o Processing.

Cuando OOP entró en juego, me di cuenta al principio de que podía crear métodos y propiedades dentro de un objeto para poder usarlos y reutilizarlos. Todo era muy abstracto y difícil de procesar, pero los lenguajes de programación en sí mismos eran mucho mejores, pero al principio dio un salto de fe hacer esas conexiones.

Kobby
fuente
wow, una parte de eso no tenía ningún sentido. "Todo era muy abstracto y difícil de procesar entre clases e instancias de objetos, etc. Pero los lenguajes de programación se volvieron mucho más fáciles de entender una vez que obtuve POO. Pero al principio me costó un poco hacer esas conexiones"
-2

Receta

Buena comprensión de OOP = buen mentor o buenos libros o ambos + interés personal + práctica.

Interés personal

Desde mi experiencia personal, el interés personal recorre un largo camino para cruzar el puente de la programación de procedimientos a OOP con los aportes correctos de mentores o buenos libros o ambos combinados .

Practica, practica y practica

Mi mejor amigo para comprender mejor la POO no ha sido más que práctica. Esto definitivamente fomentará tus habilidades de OOP.

Como dice el refrán "No hay sustituto para el trabajo duro y no hay atajo para el éxito".

¡Buena suerte!

Karthik Sreenivasan
fuente