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?
object-oriented
gablin
fuente
fuente
Respuestas:
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:
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.
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.
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.
fuente
Cat
clase que heredaMammal
, use un ejemplo real de un programa real que hubiéramos escrito procesalmente. Como una estructura de datos simple.Creo que hay algunos factores que aún no se han mencionado.
En primer lugar, al menos en "OOP puro" (por ejemplo, Smalltalk) donde todo es un objeto, debe torcer su mente en una configuración bastante poco natural para pensar en un número (por un solo ejemplo) como un objeto inteligente en lugar de solo un valor, ya que en realidad
21
(por ejemplo) realmente es solo un valor. Esto se vuelve especialmente problemático cuando, por un lado, le dicen que una gran ventaja de OOP es modelar la realidad más de cerca, pero comienza tomando lo que se parece mucho a una vista inspirada en el LSD, incluso de las partes más básicas y obvias de realidad.En segundo lugar, la herencia en OOP tampoco sigue muy de cerca los modelos mentales de la mayoría de las personas. Para la mayoría de las personas, clasificar las cosas más específicamente no tiene ningún lugar cercano a las reglas absolutas necesarias para crear una jerarquía de clases que funcione. En particular, crear un
class D
que herede de otroclass B
significa que los objetos declass D
compartir absolutamente, positivamente todas las características declass B
.class D
puede agregar características nuevas y diferentes, pero todas las características declass B
deben permanecer intactas.Por el contrario, cuando las personas clasifican las cosas mentalmente, generalmente siguen un modelo mucho más flexible. Por ejemplo, si una persona establece algunas reglas sobre lo que constituye una clase de objetos, es bastante típico que casi cualquier regla se pueda romper siempre que se sigan suficientes otras reglas. Incluso las pocas reglas que realmente no se pueden romper casi siempre se pueden "estirar" un poco de todos modos.
Solo por ejemplo, considere "auto" como una clase. Es bastante fácil ver que la gran mayoría de lo que la mayoría de la gente piensa como "autos" tiene cuatro ruedas. Sin embargo, la mayoría de las personas ha visto (al menos una foto de) un automóvil con solo tres ruedas. Algunos de nosotros de la edad adecuada también recordamos un auto de carreras o dos de principios de los 80 (más o menos) que tenía seis ruedas, y así sucesivamente. Esto nos deja básicamente con tres opciones:
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).
fuente
OOP requiere la capacidad de pensar de manera abstracta; un regalo / maldición que pocas personas, incluso los programadores profesionales, realmente tienen.
fuente
Creo que puedes resumir la dificultad básica de esta manera:
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.
fuente
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?"
fuente
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.
fuente
No estoy de acuerdo con la respuesta de dsimcha en su mayor parte:
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.
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.
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.
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.
fuente
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.
fuente
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).
fuente
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.
fuente
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.
fuente
INSTR
), porque el nombre se adjunta al tipo (comostring::find
)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.
fuente
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.
fuente
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.
fuente
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.
fuente
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).
fuente
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.
fuente
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.
fuente
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:
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.
fuente
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.
fuente
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.
fuente
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!
fuente