¿Cuál es el punto de OOP?

126

Por lo que puedo decir, a pesar de los innumerables millones o miles de millones gastados en educación, idiomas y herramientas de OOP, OOP no ha mejorado la productividad del desarrollador o la confiabilidad del software, ni ha reducido los costos de desarrollo. Pocas personas usan OOP en un sentido riguroso (pocas personas se adhieren o entienden principios como LSP); parece haber poca uniformidad o consistencia en los enfoques que las personas adoptan para modelar dominios problemáticos. Con demasiada frecuencia, la clase se usa simplemente por su azúcar sintáctica; coloca las funciones para un tipo de registro en su propio pequeño espacio de nombres.

He escrito una gran cantidad de código para una amplia variedad de aplicaciones. Aunque ha habido lugares donde el verdadero subtipo sustituible jugó un papel valioso en la aplicación, estos han sido bastante excepcionales. En general, aunque se presta mucha atención al hablar de "reutilización", la realidad es que, a menos que un código haga exactamente lo que usted quiere que haga, hay muy poca "reutilización" rentable. Es extremadamente difícil diseñar clases para que sean extensibles de la manera correcta , por lo que el costo de la extensión es normalmente tan grande que simplemente no vale la pena "reutilizar".

En muchos aspectos, esto no me sorprende. El mundo real no es "OO", y la idea implícita en OO --que podemos modelar cosas con alguna taxonomía de clase-- me parece fundamentalmente defectuosa (puedo sentarme en una mesa, un tocón de árbol, un capó de automóvil , el regazo de alguien, pero ninguno de esos es una silla). Incluso si nos movemos a dominios más abstractos, el modelado OO es a menudo difícil, contradictorio y, en última instancia, inútil (considere los ejemplos clásicos de círculos / elipses o cuadrados / rectángulos).

Entonces, ¿qué me estoy perdiendo aquí? ¿Dónde está el valor de OOP, y por qué todo el tiempo y el dinero no han logrado mejorar el software?

DrPizza
fuente
11
Su analogía es una abstracción demasiado alta para su "caso de uso" previsto; La mesa, el tocón de árbol, el capó, el regazo de alguien son composiciones de moléculas, átomos, protones, neutrones, electrones, que forman un área de superficie lo suficientemente grande como para que su trasero descanse por la fuerza de la gravedad.
icelava
38
No importa cuántas veces se inicie este mismo hilo, siempre genera mucho interés (a pesar de que los duplicados generalmente no se toleran aquí). Y, por supuesto, la respuesta elegida siempre coincide con la opinión inicial del autor de la pregunta.
TM.
44
El problema con OOP es la imposibilidad de ponerlo en contexto. Es excelente para algunos propósitos, no para todos. Es una gran herramienta Es un pésimo evangelio.
Mike Dunlavey
16
Lo siento, pero no puedo evitar la sensación de que nunca has programado usando ningún tipo de lenguaje. He aquí por qué: OOP es la base de operación para las bibliotecas de componentes base en todos los entornos modernos (Java, .NET, Python, Ruby, solo por nombrar algunos de los principales). Todas esas bibliotecas base se reutilizan a diario, por lo que si eso no cuenta, no sé qué hace. Así que no me malinterpreten aquí, pero la reutilización del código es un hecho, ¡y extremadamente común! No quiero que esto suene ofensivo de ninguna manera, solo haciendo un punto aquí.
Matthias Hryniszak
2
@George Jempty: Fue Joel Spolsky en "Cómo Microsoft perdió la guerra API" ( joelonsoftware.com/articles/APIWar.html ), el titular del pasaje es "Las transmisiones automáticas ganan el día".
GodsBoss

Respuestas:

24

No hay evidencia empírica que sugiera que la orientación a objetos sea una forma más natural para que las personas piensen sobre el mundo. Hay algo de trabajo en el campo de la psicología de la programación que muestra que OO no es de alguna manera más apropiado que otros enfoques.

Las representaciones orientadas a objetos no parecen ser universalmente más utilizables o menos utilizables.

No es suficiente simplemente adoptar métodos OO y exigir a los desarrolladores que utilicen dichos métodos, ya que eso podría tener un impacto negativo en la productividad del desarrollador, así como en la calidad de los sistemas desarrollados.

Que es de "Sobre la usabilidad de las representaciones de OO" de Comunicaciones de la ACM, octubre de 2000. Los artículos comparan principalmente OO con el enfoque orientado al proceso. Hay muchos estudios sobre cómo "piensan" las personas que trabajan con el método OO (Int. J. of Human-Computer Studies 2001, número 54, o Human-Computer Interaction 1995, vol. 10 tiene un tema completo sobre los estudios OO), y por lo que leí, no hay nada que indique algún tipo de naturalidad en el enfoque OO que lo haga más adecuado que un enfoque procesal más tradicional.

Svend
fuente
18
Funciona bien. Lo que no puede hacer es obligar a los malos programadores a escribir un buen código. Hay una tonalidad periódica y llorar contra eso por esa razón.
caos
66
@melaos: el resumen está en el medio. OOP es una herramienta en el juego de herramientas, no la única, y no hay sustituto para el entrenamiento, la experiencia y el juicio.
Mike Dunlavey
44
Me resulta divertido cuando alguien publica una "Pregunta" para discutir un punto y luego acepta la primera respuesta que respalda su punto, a pesar de que hay preguntas mejor calificadas que respaldan lo contrario. La naturaleza humana es genial.
Bill K
3
@melaos, el resumen (al menos de esos artículos) es que nada sugiere que OO sea una forma natural de pensar para las personas y, por lo tanto, no sea inherentemente superior a cualquier otra forma en que uno pueda construir programas.
Svend
66
@ Bill K: Fue una de las pocas respuestas que proporcionaron citas en lugar de agitar las manos y la mera insistencia de que OO "debe" ser mejor. Si la literatura a la que se hace referencia respalda la noción de que la OO no es una mejora particular o un beneficio particular, y por lo tanto apoya mi posición original, no estoy seguro de por qué debería ignorarla. ¿Puede proporcionar referencias similares que contrarresten mi OP?
DrPizza el
119

El mundo real no es "OO", y la idea implícita en OO --que podemos modelar cosas con alguna taxonomía de clase-- me parece fundamentalmente defectuosa

Si bien esto es cierto y ha sido observado por otras personas (tome Stepanov, inventor de la STL), el resto no tiene sentido. OOP puede ser defectuoso y ciertamente no es una bala de plata, pero hace que las aplicaciones a gran escala sean mucho más simples porque es una excelente manera de reducir las dependencias. Por supuesto, esto solo es cierto para el diseño "bueno" de OOP. El diseño descuidado no dará ninguna ventaja. Pero un buen diseño desacoplado puede modelarse muy bien con OOP y no con otras técnicas.

Hay modelos mucho mejores y más universales (me viene a la mente el modelo tipo Haskell ), pero estos también son a menudo más complicados y / o difíciles de implementar de manera eficiente. OOP es una buena compensación entre extremos.

Konrad Rudolph
fuente
10
Me parece interesante que esto tenga más votos positivos que la pregunta, y la respuesta aprobada, combinada.
Brad Gilbert
15
El sistema de tipos de Haskell me parece mucho más intuitivo que OO.
axblount
44
@Konrad: "pero hace que las aplicaciones a gran escala sean mucho más simples" - hmmm, no estoy seguro de que sea cierto. Los hace más fáciles de mantener en el sentido de que cambiar una cosa no debería romper otra, sino que es más simple. Eso es algo que hay que tragar ...
Mitch Wheat
2
@BradGilbert: por supuesto, el autor de la pregunta seleccionó una respuesta que se alinea perfectamente con la opinión en su pregunta inicial. Lo que plantea la pregunta, ¿por qué molestarse en hacer la pregunta si ya ha decidido su respuesta?
TM.
2
@Mitch: iría tan lejos como afirmar que no puede (a partir de hoy) escribir aplicaciones a gran escala sin algún tipo de orientación a objetos. A gran escala aquí es> 1M LOC.
Konrad Rudolph, el
45

OOP no se trata de crear clases reutilizables, se trata de crear clases utilizables.

Brian Leahy
fuente
77
¡Buena esa! Y muy cierto.
Toon Krijthe
1
Lo suficientemente justo. Pero luego no resuelve el problema de "reinventar la rueda", que es bastante serio en el desarrollo de software, en lugar de tener una biblioteca que tiene N pares de ojos buscando fallas, tenemos N bibliotecas con un par de ojos haciendo entonces. Hay tantas clases utilizables que puede construir antes de que necesite comenzar a reutilizarlas. Y OOP en mi opinión educada, es fundamentalmente defectuoso en exactamente esa área - reutilización de código. Oculta los datos y los "combina" con métodos, haciendo que dichos datos sean inaccesibles o apenas interoperables.
amn
42

Con demasiada frecuencia, la clase se usa simplemente por su azúcar sintáctica; coloca las funciones para un tipo de registro en su propio pequeño espacio de nombres.

Sí, también encuentro que esto es demasiado frecuente. Esto no es programación orientada a objetos. Es programación basada en objetos y programación centrada en datos. En mis 10 años de trabajo con OO Languages, veo a personas que realizan principalmente Programación basada en objetos. OBP se descompone muy rápidamente en mi humilde opinión, ya que esencialmente está obteniendo lo peor de ambas palabras: 1) Programación de procedimientos sin adherirse a la metodología probada de programación estructurada y 2) OOP sin adherirse a la metodología probada de OOP.

OOP bien hecho es una cosa hermosa. Hace que los problemas muy difíciles sean fáciles de resolver, y para los no iniciados (que no intentan parecer pomposos allí), casi puede parecer mágico. Dicho esto, OOP es solo una herramienta en la caja de herramientas de metodologías de programación. No es la metodología be all end all all. Simplemente se adapta bien a las aplicaciones de grandes empresas.

La mayoría de los desarrolladores que trabajan en lenguajes OOP están utilizando ejemplos de OOP realizados correctamente en los marcos y tipos que usan a diario, pero simplemente no son conscientes de ello. Aquí hay algunos ejemplos muy simples: ADO.NET, Hibernate / NHibernate, Logging Frameworks, varios tipos de colección de idiomas, la pila ASP.NET, la pila JSP, etc. Estas son todas las cosas que dependen en gran medida de la OOP en sus bases de código.

Daniel Auger
fuente
32

La reutilización no debería ser un objetivo de OOP, o cualquier otro paradigma para el caso.

La reutilización es un efecto secundario de un buen diseño y un nivel adecuado de abstracción. El código logra la reutilización haciendo algo útil, pero no tanto como para hacerlo inflexible. No importa si el código es OO o no: reutilizamos lo que funciona y no es trivial hacerlo nosotros mismos. Eso es pragmatismo.

La idea de OO como una nueva forma de reutilizar a través de la herencia es fundamentalmente errónea. Como notan, las violaciones de LSP abundan. En cambio, OO se considera adecuadamente como un método para gestionar la complejidad de un dominio problemático. El objetivo es la mantenibilidad de un sistema a lo largo del tiempo. La herramienta principal para lograr esto es la separación de la interfaz pública de una implementación privada. Esto nos permite tener reglas como "Esto solo debe modificarse usando ..." aplicadas por el compilador, en lugar de la revisión de código.

Al usar esto, estoy seguro de que estará de acuerdo, nos permite crear y mantener sistemas enormemente complejos. Hay mucho valor en eso, y no es fácil hacerlo en otros paradigmas.

theschmitzer
fuente
3
cierto acerca de la reutilización y OO siendo preocupaciones separadas.
Dan Rosenstark
28

Al borde de lo religioso, pero diría que estás pintando una imagen demasiado sombría del estado de la OOP moderna. Yo diría que en realidad ha reducido los costos, hecho que los grandes proyectos de software sean manejables, etc. Eso no significa que haya resuelto el problema fundamental del desorden del software, y no significa que el desarrollador promedio sea un experto en OOP. Pero la modularización de la función en componentes de objeto ciertamente ha reducido la cantidad de código de espagueti en el mundo.

Puedo pensar en docenas de bibliotecas fuera de mi cabeza que son bellamente reutilizables y que han ahorrado tiempo y dinero que nunca se pueden calcular.

Pero en la medida en que la POO ha sido una pérdida de tiempo, diría que se debe a la falta de capacitación del programador, agravada por la curva de aprendizaje empinada de aprender un mapeo de POO específico del idioma. Algunas personas "obtienen" POO y otras nunca lo harán.

usuario2189331
fuente
2
Acabo de darte un voto positivo que te arrojó por encima de 2000 puntos, con suerte se mantendrá. : P
Jason Bunting
55
Es raro ver que la OOP se enseñe de manera efectiva.
Jon W
Su respuesta se parece mucho a la dada por los entrenadores Agile / Scrum cuando se le pregunta si tiene sentido: "es muy útil si lo hace bien; si falla, debe estar haciéndolo mal". Es fácil arrojar palabras como "reutilizable" y "mantenible", pero no es fácil cuantificar estas cualidades en el código real, ni existe una receta que le indique cómo escribir una buena POO (a pesar de que miles de libros intentan hacerlo) . También tenemos la mala costumbre de ignorar ostensiblemente el hardware, lo que lleva a un desempeño horrible en el altar de evitar la optimización prematura.
Tom
21

Creo que el uso de objetos de contexto opaco (HANDLEs en Win32, FILE * s en C, por nombrar dos ejemplos bien conocidos: demonios, HANDLEs vive en el otro lado de la barrera del modo kernel, y realmente no se consigue mucho más encapsulado que eso) se encuentra en el código de procedimiento también; Me cuesta ver cómo esto es algo particular para OOP.

HANDLEs (y el resto de WinAPI) es OOP! C no admite OOP muy bien, por lo que no hay una sintaxis especial, pero eso no significa que no use los mismos conceptos. WinAPI es en todos los sentidos de la palabra un marco orientado a objetos.

Vea, este es el problema con cada discusión que involucra OOP o técnicas alternativas: nadie tiene clara la definición, todos están hablando de otra cosa y, por lo tanto, no se puede llegar a un consenso. Parece una pérdida de tiempo para mí.

Konrad Rudolph
fuente
1
Estaba a punto de publicar algo muy similar.
Brad Gilbert
Estoy de acuerdo en que puede usar conceptos OOP sin sintaxis especial, pero por otro lado, no creo que WinAPI sea un buen ejemplo de conceptos OOP.
Lena Schimmel el
14

Es un paradigma de programación. Diseñado para que sea más fácil para nosotros, simples mortales, dividir un problema en piezas más pequeñas y viables.

Si no lo encuentra útil ... No lo use, no pague por la capacitación y sea feliz.

Por otro lado, lo encuentro útil, así que lo haré :)

Rob Cooper
fuente
14

En relación con la programación procesal directa, el primer principio fundamental de OOP es la noción de ocultación y encapsulación de información. Esta idea lleva a la noción de la clase que separa la interfaz de la implementación. Estos son conceptos muy importantes y la base para establecer un marco de trabajo para pensar sobre el diseño del programa de una manera diferente y mejor (creo). Realmente no se puede argumentar en contra de esas propiedades: no se realiza un intercambio y siempre es una forma más limpia de modularizar las cosas.

Otros aspectos de la POO, como la herencia y el polimorfismo, también son importantes, pero, como otros han aludido, estos son comúnmente utilizados en exceso. es decir: a veces las personas usan la herencia y / o el polimorfismo porque pueden hacerlo, no porque deberían haberlo hecho. Son conceptos poderosos y muy útiles, pero deben usarse con prudencia y no son ventajas ganadoras automáticas de OOP.

Relativo a la reutilización. Estoy de acuerdo en que la reutilización se vende en exceso para OOP. Es un posible efecto secundario de objetos bien definidos, típicamente de clases más primitivas / genéricas y es un resultado directo de los conceptos de encapsulación y ocultación de información. Es potencialmente más fácil ser reutilizado porque las interfaces de clases bien definidas son simplemente más claras y algo auto documentadas.

Tall Jeff
fuente
1
La reutilización es una especie de grial para los desarrolladores de software, ¿no es así, independientemente del paradigma que usen, ya sea OO o funcional o lo que sea? Esto entra en conflicto con los requisitos siempre cambiantes hechos en el software y la pregunta parece ser la de hacer diseños que sean flexibles.
Geoglifo
"noción de la clase que separa la interfaz de la implementación" --- ¿Creía que las interfaces eran interfaces y las clases eran implementaciones? Tal vez soy un pensador demasiado orientado a los procesos, pero creo que es el polimorfismo, la variación en el código con la uniformidad en el uso, eso es lo mejor de OOP; Me imagino que "un montón de funciones C" separan una interfaz de una implementación tan bien como "una clase java". Tal vez estoy todo mal?
Jonas Kölker
2
@Jonas - Para sus "un montón de funciones de C" --- Estoy de acuerdo en que pueden separar una interfaz de una implementación, y en ese punto ESTO está comenzando a ser POO. Si el ejemplo continúa definiendo una estructura C en la que opera la API, básicamente ha creado la encapsulación (especialmente si la API funciona opacamente en la estructura) ... y luego realmente es POO en C.
Tall Jeff
12

El problema con OOP es que estaba sobrevendido.

Como Alan Kay lo concibió originalmente, era una gran alternativa a la práctica previa de tener datos sin procesar y rutinas globales.

Luego, algunos tipos de consultores de gestión se aferraron a él y lo vendieron como el mesías del software, y lemming, la academia y la industria cayeron tras él.

Ahora están dando vueltas después de que se vendan otras buenas ideas, como la programación funcional.

Entonces, ¿qué haría diferente? Mucho, y escribí un libro sobre esto. (Está agotado, no recibo ni un centavo, pero aún puede obtener copias). Amazon

Mi respuesta constructiva es mirar la programación no como una forma de modelar cosas en el mundo real, sino como una forma de codificar los requisitos.

Eso es muy diferente y se basa en la teoría de la información (a un nivel que cualquiera puede entender). Dice que la programación puede considerarse como un proceso de definición de lenguajes, y la habilidad para hacerlo es esencial para una buena programación.

Eleva el concepto de lenguajes específicos de dominio (DSL). Está totalmente de acuerdo con DRY (no te repitas). Da un gran aprobado a la generación de código. Da como resultado un software con una estructura de datos masivamente menor que la típica para las aplicaciones modernas.

Busca revigorizar la idea de que el camino a seguir radica en la inventiva, y que incluso las ideas bien aceptadas deben ser cuestionadas.

Mike Dunlavey
fuente
Frio. Dado que el libro está agotado, no querrá proporcionar archivos PDF, ¿verdad? Amazon envía LENTAMENTE a Argentina ...
Dan Rosenstark
Sospecho que en algún momento al principio del proceso, algunos buenos programadores se pusieron de moda sobre lo que podían hacer con OOP, y alguien los escuchó y pensó que eso significaba que todos podían y harían lo mismo.
caos
@Daniel: buena sugerencia. Trabajaré en eso y veré si puedo adjuntarlo a mi blogpot. Lo encontrará un poco anticuado, porque fue en el '94, pero los principios no han cambiado.
Mike Dunlavey el
1
@ Mike Dunlavey Estimado señor, ¿puedo apoyar la curiosidad de @ yar para saber si existe la posibilidad de leer / obtener su libro [al menos parcialmente] a través de Internet? Como parece que la forma de especificación / implementación de software [componente] efectiva que usted propone / desarrolla coincide estrechamente con la que [recientemente reconocí] que me gustaría aprender o que me enseñen (en lugar de, bueno, la forma de 'carga' introducida por muy bien libros de OO convencionales escritos pero dolorosamente ambiguos). Gracias de antemano [y saludos desde Rusia :)].
mlvljr 01 de
1
@mlvljr: OK. La forma más rápida podría ser simplemente escanearlo y hacer un gran archivo pdf. Veré si puedo llegar en los próximos días. No me dejen olvidar [sinceras condolencias por los recientes acontecimientos en Moscú y vítores de la empapada Massachusetts].
Mike Dunlavey
11

HANDLEs (y el resto de WinAPI) es OOP!

¿Son ellos, sin embargo? No son heredables, ciertamente no son sustituibles, carecen de clases bien definidas ... Creo que están muy lejos de "POO".

¿Alguna vez has creado una ventana con WinAPI? Entonces debe saber que define una clase ( RegisterClass), crea una instancia de ella ( CreateWindow), llama a métodos virtuales ( WndProc) y métodos de clase base ( DefWindowProc), etc. WinAPI incluso toma la nomenclatura de SmallTalk OOP, llamando a los métodos "mensajes" (mensajes de ventana).

Los identificadores pueden no ser heredables, pero hay finalJava. No les falta una clase, son un marcador de posición para la clase: eso es lo que significa la palabra "manejar". Mirando arquitecturas como MFC o .NET WinForms, es inmediatamente obvio que, excepto por la sintaxis, nada es muy diferente de WinAPI.

Konrad Rudolph
fuente
El WINAPI no es OOP. Simplemente muestra una forma de escribir código de procedimiento extensible. Las buenas técnicas son buenas sin importar si son OOP o no. Puedo escribir programas WINAPI en C y usar las mismas técnicas en mi propio código, así que supongo que C es OOP.
bruceatk
3
Puede que no sea lo que Alan Kay tenía en mente (¡búscalo en Google!), Pero de todos modos es POO.
Konrad Rudolph
11

Sí, OOP no resolvió todos nuestros problemas, lo siento. Sin embargo, estamos trabajando en SOA que resolverá todos esos problemas.

Nat
fuente
44
¿No te enteraste? SOA es el pasado. Hoy es la computación en la nube la que será nuestro salvador.
DrPizza
Realmente me pregunto si sus respuestas son irónicas o no. Me gusta la ironía, pero por lo general se rechaza, esto me hace preguntarme ...
Lena Schimmel
Creo que este es irónico, y no lo voy a rechazar. ¡Pero tampoco lo votaré! :-)
Yarik
La pregunta es bastante retórica, por lo que esta es una respuesta válida (y la mejor respuesta).
Jeff Davis
10

OOP se presta bien para programar estructuras informáticas internas como "widgets" de GUI, donde, por ejemplo, SelectList y TextBox pueden ser subtipos de Item, que tiene métodos comunes como "mover" y "cambiar el tamaño".

El problema es que el 90% de nosotros trabajamos en el mundo de los negocios donde trabajamos con conceptos comerciales como Factura, Empleado, Trabajo, Orden. Estos no se prestan tan bien a OOP porque los "objetos" son más nebulosos, están sujetos a cambios de acuerdo con la reingeniería de negocios, etc.

El peor de los casos es cuando OO se aplica con entusiasmo a las bases de datos, incluidas las "mejoras" atroces de OO a las bases de datos SQL, que se ignoran correctamente, excepto por los novatos de bases de datos que suponen que deben ser la forma correcta de hacer las cosas porque son más nuevas.

Tony Andrews
fuente
Eso es todo cierto, pero ... tal vez, el hecho de que OOP puede simplificar ALGUNOS aspectos de una aplicación no relacionados con el negocio (como la implementación de UI) es exactamente una de las razones principales por las que un desarrollador (¡finalmente!) Puede pasar más tiempo trabajando en negocios aspectos relacionados?
Yarik
10

En mi experiencia de revisar el código y el diseño de los proyectos por los que he pasado, el valor de OOP no se comprende completamente porque muchos desarrolladores no han conceptualizado adecuadamente el modelo orientado a objetos en sus mentes. Por lo tanto, no programan con diseño OO, y a menudo continúan escribiendo código de procedimiento de arriba hacia abajo, lo que hace que las clases tengan un diseño bastante plano . (si incluso puedes llamar a eso "diseño" en primer lugar)

Es bastante aterrador observar lo poco que saben los colegas sobre qué es una clase o interfaz abstracta, y mucho menos diseñar adecuadamente una jerarquía de herencia que se adapte a las necesidades del negocio.

Sin embargo, cuando está presente un buen diseño de OO, es simplemente una alegría leer el código y ver que el código encaja naturalmente en componentes / clases intuitivos. Siempre he percibido la arquitectura y el diseño del sistema como el diseño de los diversos departamentos y trabajos del personal en una empresa: todos están ahí para lograr un cierto trabajo en el gran esquema de las cosas, emitiendo la sinergia necesaria para impulsar la organización / sistema hacia adelante.

Eso, por supuesto, es bastante raro por desgracia. Al igual que la proporción de objetos físicos bellamente diseñados frente a objetos horrendamente diseñados en el mundo, lo mismo se puede decir sobre la ingeniería y el diseño de software. Tener las buenas herramientas a disposición no necesariamente confiere buenas prácticas y resultados.

revs icelava
fuente
1
Nunca he logrado la fase de pura alegría procesal o POO mientras leía el código. :)
bruceatk
1
Pura alegría, no, pero ¿una pequeña sonrisa quizás?
Dan Rosenstark
9

Tal vez un capó, una falda o un árbol no es una silla, pero todos son ISittable.

Johnno Nolan
fuente
2
Nunca ha tenido que usar un lenguaje OO sin interfaces, ¿verdad? Tienes suerte.
finnw
No, no lo son. Son cosas que no fueron diseñadas para sentarse, así que creo que para ser fieles a la analogía, no habrían sido escritas para implementar la interfaz ISittable. Son de una biblioteca de terceros, y ahora que está escribiendo un proyecto que involucra un dominio que incluye sentarse, encontrará que tendrá que escribir objetos adaptadores para envolverlos y hacerlos ISittable. ¿Ver? No muy parecido al mundo real.
EricS
8

Creo que esas cosas del mundo real son objetos

¿Tú lo haces?

¿Qué métodos tiene una factura? Oh espera. No puede pagarse a sí mismo, no puede enviarse a sí mismo, no puede compararse con los artículos que el proveedor realmente entregó. No tiene ningún método en absoluto; Es totalmente inerte y no funcional. Es un tipo de registro (una estructura, si lo prefiere), no un objeto.

Del mismo modo, las otras cosas que mencionas.

El hecho de que algo sea real no lo convierte en un objeto en el sentido OO de la palabra. Los objetos OO son un acoplamiento peculiar de estado y comportamiento que pueden actuar por sí mismos. Eso no es algo abundante en el mundo real.

DrPizza
fuente
2
Tome cualquier máquina, dispositivo electrónico o seres vivos, esos son todos "acoplamientos de estado y comportamiento".
TM.
1
Estoy de acuerdo en que métodos como Send () o Pay () no son "naturales" para las facturas. Pero, por ejemplo, ¿qué pasa con el monto total como un atributo derivado pero INHERENTE de una factura? ¿No es un ejemplo de lo que OOP permite modelar de una manera muy "natural" incluso para entidades de la vida real totalmente inertes? No es un gran logro en sí mismo, pero aún así ...
Yarik
@Yarik: Estas entidades "inertes" conducen a un diseño basado en objetos. Para mí, el único OO apropiado es la simulación, donde los objetos "pueden actuar por sí mismos" , como dice esta respuesta. Si OO es la única forma manejable de lograr algo, está bien, pero de lo contrario, ¿no podemos apegarnos a algo más simple y más como resolver el problema?
7

He estado escribiendo código OO durante los últimos 9 años más o menos. Además de usar la mensajería, me resulta difícil imaginar otro enfoque. El principal beneficio que veo está totalmente en línea con lo que dijo CodingTheWheel: modularización. OO, naturalmente, me lleva a construir mis aplicaciones a partir de componentes modulares que tienen interfaces limpias y responsabilidades claras (es decir, código débilmente acoplado, altamente cohesivo con una clara separación de preocupaciones).

Creo que donde OO se descompone es cuando las personas crean jerarquías de clase profundamente anidadas. Esto puede conducir a la complejidad. Sin embargo, factorizar la finitud común en una clase base, luego reutilizar eso en otras clases descendientes es algo muy elegante, ¡en mi humilde opinión!

Sean Kearon
fuente
7

En primer lugar, las observaciones son algo descuidadas. No tengo cifras sobre la productividad del software, y no tengo buenas razones para creer que no va a subir. Además, dado que hay muchas personas que abusan de la OO, el buen uso de la OO no necesariamente causaría una mejora de la productividad, incluso si la OO fuera lo más importante desde la mantequilla de maní. Después de todo, es probable que un cirujano cerebral incompetente sea peor que ninguno, pero uno competente puede ser invaluable.

Dicho esto, OO es una forma diferente de organizar las cosas, adjuntando código de procedimiento a los datos en lugar de hacer que el código de procedimiento opere en los datos. Esto debería ser al menos una pequeña victoria en sí misma, ya que hay casos en los que el enfoque OO es más natural. Después de todo, nada impide que alguien escriba una API de procedimiento en C ++, por lo que la opción de proporcionar objetos hace que el lenguaje sea más versátil.

Además, hay algo que OO hace muy bien: permite que el código antiguo llame al nuevo código automáticamente, sin cambios. Si tengo un código que gestiona las cosas de manera procesal, y agrego un nuevo tipo de cosas que es similar pero no idéntico a uno anterior, tengo que cambiar el código de procedimiento. En un sistema OO, heredo la funcionalidad, cambio lo que me gusta y el nuevo código se usa automáticamente debido al polimorfismo. Esto aumenta la localidad de los cambios, y eso es algo bueno.

La desventaja es que un buen OO no es gratis: requiere tiempo y esfuerzo para aprenderlo correctamente. Dado que es una palabra de moda importante, hay muchas personas y productos que lo hacen mal, solo por el hecho de hacerlo. No es más fácil diseñar una buena interfaz de clase que una buena API de procedimiento, y hay todo tipo de errores fáciles de hacer (como jerarquías de clase profundas).

Piense en ello como un tipo diferente de herramienta, no necesariamente en general mejor. Un martillo además de un destornillador, digamos. Quizás eventualmente salgamos de la práctica de la ingeniería de software como saber qué llave utilizar para martillar el tornillo.

David Thornley
fuente
Me gusta tu último párrafo lo mejor.
Mike Dunlavey
6

@Sean

Sin embargo, factorizar la finitud común en una clase base, luego reutilizar eso en otras clases descendientes es algo muy elegante, ¡en mi humilde opinión!

Pero los desarrolladores "procesales" han estado haciendo eso durante décadas de todos modos. La sintaxis y la terminología pueden diferir, pero el efecto es idéntico. Hay más en OOP que "reutilizar la funcionalidad común en una clase base", e incluso podría ir tan lejos como para decir que eso es difícil de describir como OOP; llamar a la misma función desde diferentes bits de código es una técnica tan antigua como el propio subprocedimiento.

DrPizza
fuente
6

@Konrad

OOP puede ser defectuoso y ciertamente no es una bala de plata, pero hace que las aplicaciones a gran escala sean mucho más simples porque es una excelente manera de reducir las dependencias

Ese es el dogma. No veo lo que hace que la POO sea significativamente mejor a este respecto que la programación de procedimientos de antaño. Cada vez que hago una llamada de procedimiento, me estoy aislando de los detalles de la implementación.

DrPizza
fuente
6

Para mí, hay mucho valor en la sintaxis de OOP. El uso de objetos que intentan representar cosas reales o estructuras de datos a menudo es mucho más útil que tratar de usar un montón de diferentes funciones planas (o "flotantes") para hacer lo mismo con los mismos datos. Hay un cierto "flujo" natural a las cosas con buena OOP que tiene más sentido para leer, escribir y mantener a largo plazo.

No necesariamente importa que una Factura no sea realmente un "objeto" con funciones que puede realizar por sí misma; la instancia del objeto puede existir solo para realizar funciones en los datos sin tener que saber qué tipo de datos hay realmente allí. La función "invoice.toJson ()" se puede llamar con éxito sin tener que saber qué tipo de datos es "factura": el resultado será Json, sin importar si proviene de una base de datos, XML, CSV o incluso de otro objeto JSON . Con funciones de procedimiento, de repente tiene que saber más sobre sus datos y terminar con funciones como "xmlToJson ()", "csvToJson ()", "dbToJson ()", etc. Con el tiempo se convierte en un completo desastre y un ENORME dolor de cabeza si alguna vez cambia el tipo de datos subyacente.

El objetivo de OOP es ocultar la implementación real abstrayéndola. Para lograr ese objetivo, debe crear una interfaz pública. Para facilitar su trabajo al crear esa interfaz pública y mantener las cosas SECAS, debe usar conceptos como clases abstractas, herencia, polimorfismo y patrones de diseño.

Entonces, para mí, el objetivo principal de OOP es facilitar el mantenimiento y los cambios futuros del código. Pero incluso más allá de eso, realmente puede simplificar mucho las cosas cuando se hace correctamente de una manera que el código de procedimiento nunca podría. No importa si no coincide con el "mundo real": la programación con código no interactúa con objetos del mundo real de todos modos. OOP es solo una herramienta que hace que mi trabajo sea más fácil y rápido; lo haré cualquier día.

Vance Lucas
fuente
5

@CodingTheWheel

Pero en la medida en que la POO ha sido una pérdida de tiempo, diría que se debe a la falta de capacitación del programador, agravada por la curva de aprendizaje empinada de aprender un mapeo de POO específico del idioma. Algunas personas "obtienen" POO y otras nunca lo harán.

Sin embargo, no sé si eso es realmente sorprendente. Creo que los enfoques técnicamente sólidos (LSP es lo obvio) hacen que sea difícil de usar , pero si no los usamos, el código se vuelve frágil e inextensible de todos modos (porque ya no podemos razonar al respecto). Y creo que los resultados contraintuitivos a los que nos lleva OOP hacen que no sea sorprendente que la gente no lo capte.

Más significativamente, dado que el software ya es fundamentalmente demasiado difícil para que los humanos normales escriban de manera confiable y precisa, ¿deberíamos realmente ensalzar una técnica que se enseña mal de manera consistente y parece difícil de aprender? Si los beneficios fueran claros, podría valer la pena perseverar a pesar de la dificultad, pero ese no parece ser el caso.

DrPizza
fuente
El "entrenamiento adecuado" debe ser muy largo, abstracto y complejo en estos días. Lo sé: enseño programación. Hace décadas, muchas personas podían aprender a hacer algún tipo de programación. Creo que eso ya no es cierto.
5

@Jeff

En relación con la programación procesal directa, el primer principio fundamental de OOP es la noción de ocultación y encapsulación de información. Esta idea lleva a la noción de la clase que separa la interfaz de la implementación.

¿Cuál tiene la implementación más oculta: iostreams de C ++ o FILE * s de C?

Creo que el uso de objetos de contexto opaco (HANDLEs en Win32, FILE * s en C, por nombrar dos ejemplos bien conocidos: demonios, HANDLEs vive en el otro lado de la barrera del modo kernel, y realmente no se consigue mucho más encapsulado que eso) se encuentra en el código de procedimiento también; Me cuesta ver cómo esto es algo particular para OOP.

Supongo que eso puede ser parte de por qué estoy luchando por ver los beneficios: las partes que obviamente son buenas no son específicas de OOP, mientras que las partes que son específicas de OOP no son obviamente buenas. (Esto no quiere decir que sean necesariamente malas, sino que no he visto la evidencia de que sean ampliamente aplicables y consistentemente beneficiosas).

DrPizza
fuente
5

En el único blog de desarrollo que leí, por ese tipo de Joel-On-Software-Fundador-de-SO, leí hace mucho tiempo que OO no conduce a aumentos de productividad. La gestión automática de memoria sí. Frio. ¿Quién puede negar los datos?

Todavía creo que OO es para no OO lo que la programación con funciones es programar todo en línea.

(Y debo saber, ya que comencé con GWBasic.) Cuando refactoriza el código para usar funciones, se variable2654convierte variable3en el método en el que se encuentra. O, mejor aún, tiene un nombre que puede entender, y si la función es corta , se llama value y eso es suficiente para una comprensión total.

Cuando el código sin funciones se convierte en código con métodos, puede eliminar millas de código.

Al refactorizar código para ser verdaderamente OO, b, c, q, y Zconvertirse this, this, thisy this. Y como no creo en el uso de la thispalabra clave, puede eliminar millas de código. En realidad, puedes hacerlo incluso si lo usas this.



No creo que OO sea una metáfora natural.

Tampoco creo que el lenguaje sea una metáfora natural, ni creo que los "olores" de Fowler sean mejores que decir "este código sabe mal". Dicho esto, creo que OO no se trata de metáforas naturales y que las personas que piensan que los objetos simplemente salen hacia ti básicamente están perdiendo el punto. Usted define el universo de objetos, y mejores universos de objetos dan como resultado un código que es más corto, más fácil de entender, funciona mejor o todo esto (y algunos criterios que estoy olvidando). Creo que las personas que usan los objetos naturales de los clientes / dominios como objetos de programación carecen del poder para redefinir el universo.

Por ejemplo, cuando hace un sistema de reserva de una aerolínea, lo que llama una reserva podría no corresponder en absoluto a una reserva legal / comercial.



Algunos de los conceptos básicos son herramientas realmente geniales

Creo que la mayoría de la gente exagera con todo eso de "cuando tienes un martillo, son todos clavos". Creo que el otro lado de la moneda / espejo es igual de cierto: cuando tienes un dispositivo como polimorfismo / herencia, comienzas a encontrar usos donde cabe como un guante / calcetín / lente de contacto. Las herramientas de OO son muy poderosas. La herencia única es, creo, absolutamente necesaria para que la gente no se deje llevar, a pesar de mi propio software de herencia múltiple.



¿Cuál es el punto de OOP?

Creo que es una excelente manera de manejar una base de código absolutamente masiva. Creo que le permite organizar y reorganizar su código y le brinda un lenguaje para hacerlo (más allá del lenguaje de programación en el que está trabajando), y modulariza el código de una manera bastante natural y fácil de entender.

OOP está destinado a ser malentendido por la mayoría de los desarrolladores

Esto se debe a que es un proceso revelador como la vida: entiendes OO cada vez más con experiencia, y comienzas a evitar ciertos patrones y a emplear a otros a medida que te vuelves más sabio. Uno de los mejores ejemplos es que deja de usar la herencia para las clases que no controla y prefiere el patrón Fachada .



Con respecto a su mini ensayo / pregunta

Quería mencionar que tienes razón. La reutilización es un sueño imposible, en su mayor parte. Aquí hay una cita de Anders Hejilsberg sobre ese tema (brillante) de aquí :

Si le pide a los programadores principiantes que escriban un control de calendario, a menudo piensan: "¡Oh, voy a escribir el mejor control de calendario del mundo! Será polimórfico con respecto al tipo de calendario. Tendrá visualizadores, y mungers, y esto, aquello y lo otro ". Necesitan enviar una aplicación de calendario en dos meses. Pusieron toda esta infraestructura en su lugar en el control y luego pasaron dos días escribiendo una aplicación de calendario horrible encima. Pensarán: "En la próxima versión de la aplicación, voy a hacer mucho más".

Sin embargo, una vez que comienzan a pensar cómo van a implementar todas estas otras concreciones de su diseño abstracto, resulta que su diseño es completamente incorrecto. Y ahora se han pintado en una esquina y tienen que tirar todo. Lo he visto una y otra vez. Creo firmemente en ser minimalista. A menos que realmente vaya a resolver el problema general, no intente establecer un marco para resolver uno específico, porque no sabe cómo debería ser ese marco.

Yar
fuente
4

¿Alguna vez has creado una ventana con WinAPI?

Más veces de las que me gustaría recordar.

Entonces debe saber que define una clase (RegisterClass), crea una instancia de ella (CreateWindow), llama a métodos virtuales (WndProc) y métodos de clase base (DefWindowProc) y así sucesivamente. WinAPI incluso toma la nomenclatura de SmallTalk OOP, llamando a los métodos "mensajes" (mensajes de ventana).

Entonces también sabrá que no envía mensajes por sí mismo, lo que es un gran vacío. También tiene subclases de mierda.

Los identificadores pueden no ser heredables, pero hay un final en Java. No les falta una clase, son un marcador de posición para la clase: eso es lo que significa la palabra "manejar". Mirando arquitecturas como MFC o .NET WinForms, es inmediatamente obvio que, excepto por la sintaxis, nada es muy diferente de WinAPI.

No son heredables ni en la interfaz ni en la implementación, son mínimamente sustituibles, y no son sustancialmente diferentes de lo que los codificadores de procedimientos han estado haciendo desde siempre.

¿Es esto realmente? Los mejores bits de OOP son solo ... ¿código de procedimiento tradicional? Ese es el gran problema?

DrPizza
fuente
Debe recordar que la interfaz Win32 fue básicamente una reimplementación de Win16. Que fue diseñado hace más de dos décadas.
Brad Gilbert
Cuando estaba aprendiendo a programar en la universidad, principalmente en C pero también en otros lenguajes, nos enseñaron algunas ideas básicas y nos expusieron a algunas plataformas, pero se entendió que la responsabilidad general de crear diseños, marcos, mejores prácticas, etc. dependería de nosotros en el lugar de trabajo. Aprendimos técnicas, no cosmovisiones. Con OO, debes aprender una religión antes de poder hacer algo útil, y esto determina por completo cómo ves las soluciones. No creo que sea realmente correcto.
4

Estoy completamente de acuerdo con la respuesta de InSciTek Jeff, solo agregaré las siguientes mejoras:

  • Ocultación y encapsulación de información: crítico para cualquier código mantenible. Se puede hacer con cuidado en cualquier lenguaje de programación, no requiere características OO, pero hacerlo hará que su código sea un poco similar a OO.
  • Herencia: Hay un dominio de aplicación importante para el cual todas esas relaciones OO son un tipo de y contiene una combinación perfecta: las interfaces gráficas de usuario. Si intenta crear GUI sin compatibilidad con el lenguaje OO, terminará construyendo características similares a OO de todos modos, y es más difícil y más propenso a errores sin la compatibilidad con el lenguaje. Glade (recientemente) y X11 Xt (históricamente), por ejemplo.

El uso de características OO (especialmente jerarquías abstractas profundamente anidadas), cuando no tiene sentido, no tiene sentido. Pero para algunos dominios de aplicación, realmente hay un punto.

revs Liudvikas Bukys
fuente
Sí, creo que deberías usar OOP para objetos, programación funcional para funciones ...
Svante
4

Creo que la calidad más beneficiosa de OOP es la ocultación / gestión de datos. Sin embargo, hay MUCHOS ejemplos en los que se utiliza mal la POO y creo que aquí es donde entra la confusión.

El hecho de que pueda convertir algo en un objeto no significa que deba hacerlo. Sin embargo, si hacerlo hará que su código sea más organizado / fácil de leer, entonces definitivamente debería hacerlo.

Un gran ejemplo práctico donde OOP es muy útil es con una clase de "producto" y objetos que uso en nuestro sitio web. Dado que cada página es un producto, y cada producto tiene referencias a otros productos, puede ser muy confuso a qué producto se refieren los datos que tiene. ¿Es esta variable "strURL" el enlace a la página actual, a la página de inicio o a la página de estadísticas? Claro que podría hacer todo tipo de variables diferentes que se refieran a la misma información, pero proCurrentPage-> strURL, es mucho más fácil de entender (para un desarrollador).

Además, adjuntar funciones a esas páginas es mucho más limpio. Puedo hacer proCurrentPage-> CleanCache (); Seguido por proDisplayItem-> RenderPromo (); Si acabo de llamar a esas funciones y hacer que asuma que los datos actuales están disponibles, quién sabe qué tipo de maldad ocurriría. Además, si tuviera que pasar las variables correctas a esas funciones, volvería al problema de tener todo tipo de variables para los diferentes productos.

En cambio, usando objetos, todos los datos y funciones de mi producto son agradables, limpios y fáciles de entender.

Sin embargo. El gran problema con OOP es cuando alguien cree que TODO debería ser OOP. Esto crea muchos problemas. Tengo 88 tablas en mi base de datos. Solo tengo alrededor de 6 clases, y tal vez debería tener alrededor de 10. Definitivamente no necesito 88 clases. La mayoría de las veces acceder directamente a esas tablas es perfectamente comprensible en las circunstancias en que lo uso, y la OOP en realidad haría más difícil / tedioso llegar a la funcionalidad central de lo que está ocurriendo.

Creo que un modelo híbrido de objetos donde útil y de procedimiento donde práctico es el método más efectivo de codificación. Es una pena que tengamos todas estas guerras religiosas donde la gente aboga por usar un método a expensas de los otros. Ambos son buenos y ambos tienen su lugar. La mayoría de las veces, hay usos para ambos métodos en cada proyecto más grande (en algunos proyectos más pequeños, un solo objeto o algunos procedimientos pueden ser todo lo que necesita).

Jeff Davis
fuente
3

No me interesa la reutilización tanto como la legibilidad. Esto último significa que su código es más fácil de cambiar. Eso solo vale en oro en el oficio de construir software.

Y OO es una forma bastante efectiva de hacer que sus programas sean legibles. Reutilizar o no reutilizar.

Federico el tonto
fuente
2

"El mundo real no es" OO ","

De Verdad? Mi mundo está lleno de objetos. Estoy usando uno ahora. Creo que hacer que los "objetos" de software modelen los objetos reales podría no ser tan malo.

Los diseños OO para cosas conceptuales (como Windows, no ventanas del mundo real, pero los paneles de visualización en el monitor de mi computadora) a menudo dejan mucho que desear. Pero para cosas del mundo real como facturas, pedidos de envío, reclamos de seguros y demás, creo que esas cosas del mundo real son objetos. Tengo una pila en mi escritorio, por lo que deben ser reales.

S.Lott
fuente
2

El objetivo de OOP es darle al programador otro medio para describir y comunicar una solución a un problema de código a máquinas y personas. La parte más importante de eso es la comunicación con las personas. OOP le permite al programador declarar lo que significan en el código a través de reglas que se aplican en el lenguaje OO.

Contrariamente a muchos argumentos sobre este tema, los conceptos OOP y OO son omnipresentes en todo el código, incluido el código en lenguajes que no son OOP como C. Muchos programadores avanzados que no son OO aproximarán las características de los objetos incluso en lenguajes no OO.

Tener OO integrado en el lenguaje simplemente le da al programador otro medio de expresión.

La mayor parte de escribir código no es la comunicación con la máquina, esa parte es fácil, la mayor parte es la comunicación con programadores humanos.

Bernard Igiri
fuente