¿Las cosas orientadas a objetos son realmente tan importantes? [cerrado]

8

Durante años, he estado haciendo cosas algorítmicas, escribiendo estructuras de datos escalables para la búsqueda en Internet, por ejemplo, árboles de búsqueda binaria aleatoria para recomendación automática, mapas de bits, algoritmos basados ​​en la sabiduría de la multitud que usan gráficos, escribiendo algunos algoritmos interesantes de aprendizaje automático como agrupación, detección de anomalías, trabajando en cosas de recuperación de información, etc.

Hay una cosa común en las cosas que he mencionado anteriormente. Todo lo anterior; cada uno si está codificado en un lenguaje como C ++ requiere un puñado de clases. Quiero decir que son problemas interesantes, pero no son complejos en términos de material orientado a objetos muy cargados. Nunca he usado herencia, material virtual, etc. Aunque he usado mucho la programación genérica, las plantillas, etc.

Me encanta C ++ (- Cosas voluminosas de OO, como me gusta lo que dice Joe Armstrong, creador de Erlang, en OO World si pides un plátano, obtienes una gran jungla junto con un gorila que sostiene el plátano). Disfruto codificando en otros lenguajes como Java, Python también.

Ahora mi pregunta es, ya que estoy disfrutando el tipo de proyectos / Algoritmos en los que estoy trabajando, ¿realmente necesito aprender cosas OO, seré un mejor codificador / diseñador simplemente usando cosas como Herencia, Polimorfismo dinámico (virtuales)? O puedo pasar al mundo de la programación funcional (no lo he hecho hasta ahora) que me atrae más, ya que puedo centrarme en las tareas / algoritmos y no dejar que las cosas de OO basadas en Kingdom Of Noun sean una regla ¿yo?

En resumen, ¿pueden / pueden ayudarme las cosas de OO para el tipo de proyectos / Algoritmos que he mencionado anteriormente?

EDITAR:

Un enlace extremadamente interesante para agregar aquí:

http://steve-yegge.blogspot.in/2006/03/execution-in-kingdom-of-nouns.html

Yavar
fuente
25
La orientación a objetos es el paradigma de programación más utilizado en la actualidad. Ignóralo bajo tu propio riesgo.
Robert Harvey
55
<sarcasmo> Nah, no te preocupes por eso. C debería ser suficiente para ti. </sarcasm>
Otávio Décio
2
Duplicado relacionado / posible: programmers.stackexchange.com/questions/7126/…
Adam Lear
16
Por supuesto, OOP / OOD está sobrevalorado. Este modelo trivial solo se puede usar para un conjunto limitado de problemas. Pero no debe ignorarlo; de lo contrario, terminará usando las herramientas incorrectas para esas áreas raras y estrechas donde la POO realmente brilla.
SK-logic
13
Linus Torvalds, ¿eres tú?
Jesse C. Slicer

Respuestas:

9

La programación orientada a objetos es realmente buena para ocultar sus complejas cosas de matemáticas detrás de palabras fáciles de entender y facilita a los menores entre ustedes usar las cosas que ha escrito. No reemplaza la programación funcional ... solo le brinda una forma realmente fácil de cambiar implementaciones o agregar comportamiento.

En su ejemplo de Árboles de búsqueda binaria aleatorizados anterior, ¿qué sucedería si le dieran el requisito de que en el Día de los Inocentes, el Aleatorizador fue reemplazado por un orden por distancia de tres chiflados? Es realmente útil crear StoogeBinaryTree : RandomBinaryTreey anular el protected int GetSortOrder (Tree a, Tree b)método, por lo que el 2 de abril, puede cambiar la implementación nuevamente RandomBinaryTreesin tener que haber cambiado nada de ese código.

En un ejemplo simple, he mostrado que agrego una pequeña porción de comportamiento y cambiamos la implementación ...

Bryan Boettcher
fuente
14
Esto no es OOP, cualquier sistema de módulo decente haría lo mismo (y, probablemente, de una manera mucho más simple). Ver módulos SML de primera clase, por ejemplo.
SK-logic
44
@ SK-logic: Y los módulos y OOP son significativamente diferentes, ¿cómo, exactamente?
DeadMG
12
@DeadMG, no hay BS sobre estados y mensajes y herencia en la definición de cualquier sistema de módulo decente. Solo encapsulado, más muchas matemáticas útiles (sé que te desmayarás en este punto).
SK-logic
2
@ SK-logic: Mis sistemas OOP no usan mensajes o herencia o estado excesivo. Encapsulan, y luego, si lo necesito, también pueden encapsular en tiempo de ejecución. Otras personas pueden hacer las suyas de manera diferente, por supuesto, pero esa es su elección, y no con OOP.
DeadMG
3
@DeadMG Entonces, ¿cuál es la diferencia entre un lenguaje orientado a objetos y uno que no lo es? ¿De qué manera, por ejemplo, Haskell o Erlang no están orientados a objetos si todo lo que se requiere para la orientación de objetos es un sistema de módulos? ¿O estás diciendo que esos son lenguajes orientados a objetos?
sepp2k
8

Si vas a hacer FP todavía con lenguajes como Haskell y Erlang que lo hacen bien, no hay necesidad de tomar el refresco OOP. FP es muy poderoso y puede hacer mucho incluso en el mundo real

Dicho esto, aprender un idioma OOP no sería algo malo. Entender múltiples formas de programar y varias metodologías funcionará a su favor. Además, si te mudas de Haskell o Erlang a Java puedes preguntarte cómo en el mundo cualquiera puede trabajar sin REPL y lambdas.

Zachary K
fuente
Y debe mencionarse que lenguajes como Clojure permiten POO pero no te limitan a estar basado en clases. Es decir, Clojure admite funciones polimórficas, interfaces, etc., todo sin la necesidad de crear una clase (al menos no de la manera en que C # / Java lo define).
Timothy Baldridge
Joe Armstrong argumenta que Erlang es más OO que C ++ o Java, no sea dogmático sobre estas cosas, o lo morderá. Haga clic en el enlace @ ¿Está Erlang orientado a objetos?
Oh, no, diablos, escribí un libro sobre Erlang ( shop.oreilly.com/product/0636920021452.do ) pero cuando la gente habla de OOP, Erlang generalmente no es lo que quieren decir
Zachary K
7

Parece que solo te has centrado en resolver un solo problema a la vez, es decir, escribir algoritmos. Pero considere cómo escribiría una aplicación GUI, por ejemplo, o alguna otra aplicación enorme que posiblemente requiera que use mucho de su algoritmo. En ese caso, conocer OO será esencial, ya que lo ayudará a simplificar su código para hacerlo más legible y más fácil de usar para otros desarrolladores, por ejemplo, creando una biblioteca que pueda cargarse como un objeto.

Uno de los patrones de diseño más importantes en la Programación Orientada a Objetos es el Patrón de Estrategia , que en el escenario anterior también lo ayudará mucho. Considere un ejemplo en el que el usuario le presentaría una entrada en la que le permitiría realizar un algoritmo. Esto podría ser fácilmente un desastre si / de lo contrario o la construcción del interruptor / caja. Al crear una interfaz común para su algoritmo y usar el Patrón de estrategia, su código sería mucho más flexible, legible, más fácil de extender y, por lo tanto, más fácil de mantener.

kba
fuente
¿Qué tiene que decir sobre los lenguajes funcionales que implementan el patrón estratégico de manera muy elegante (se podría argumentar, más aún) sin objetos?
Steven Evers
44
-1 Por suponer que 1) las aplicaciones grandes son imposibles sin OOP, y 2) que la carga de la biblioteca está de alguna manera vinculada a OOP. Lea sobre el despacho múltiple (y el problema de expresión), y comienza a darse cuenta de que Java / C # / C ++ en realidad dificulta muchas tareas al colocar restricciones innecesarias en el programador.
Timothy Baldridge
1
Por favor, dígame cómo una biblioteca que podría cargarse como un objeto es mejor que una que no se carga como un objeto.
aseq
@SnOrfus Estoy abogando por OO, porque ese es el mundo con el que estoy más familiarizado. No estoy familiarizado con el patrón de estrategia de lenguaje funcional
kba
2
"patrón de estrategia" Esa es la única cosa que me disgusta más sobre OOP que cualquier otra cosa. ¿Por qué todo tiene que tener un patrón? La única razón por la que se tuvieron que inventar cosas como el patrón de visitante fue porque el lenguaje utilizado era tan limitado y complejo, que era imposible iterar sobre una estructura de datos sin un patrón. Elimine la increíble complejidad de los lenguajes modernos de OOP y de repente los patrones como funciones simples. Los patrones son simplemente una forma de hacer que OOP suene como si tuviera una idea de lo que está haciendo </rant>
Timothy Baldridge
6

El enfoque orientado a objetos tuvo éxito debido a un aspecto crucial: le permite abordar sistemas de complejidad esencial significativa sin introducir demasiada complejidad accidental . Esto puede ser casi ignorado cuando trabajas en sistemas de cosecha propia, pero se vuelve muy importante cuando construyes sistemas a gran escala.

Los elementos clave del enfoque orientado a objetos se pueden explicar a un programador con una amplia exposición a la programación de procedimientos en cuestión de días, lo que ayudó a que la técnica ganara popularidad rápidamente (esto no quiere decir que pueda convertirse en un experto en un Un par de días: es similar a aprender ajedrez: puedes aprender a mover tus piezas en menos de diez minutos, pero lleva años dominar el juego).

Las técnicas de programación funcional están ganando más importancia con la introducción de soporte de lenguaje para ellas en los lenguajes principales (lambdas y delegados anónimos de C #, lambdas de C ++ e incluso clases anónimas de Java, hasta cierto punto). Es muy útil comprender estas técnicas, pero están diseñadas para abordar problemas más localizados en la escala táctica . Las técnicas orientadas a objetos, por otro lado, siguen siendo relevantes en la escala estratégica , especialmente en el contexto de equipos más grandes.

dasblinkenlight
fuente
3
Mientras que aprecio el sentimiento expresado con respecto a la complejidad, lamentablemente en la práctica sucede lo contrario. Los lenguajes OO tienen una habilidad especial para introducir hinchazón y complejidad innecesarias. Eso a menudo no es culpa del idioma. Pero creo que si una técnica es propensa a hacer que muchas personas la usen incorrectamente, puede ser algo defectuosa. No importa cuán agradable suene en teoría.
aseq
1
+1 para dasblinkenlight y no estoy de acuerdo con aseq. En particular, creo que OO se correlaciona estrechamente con lo que se requiere para hacer cualquier GUI basada en eventos, y dado que hay mucha actividad en la interfaz de usuario, hay mucha actividad en los marcos de OO. Haga una interfaz de usuario sin un marco OO, y en realidad terminará construyendo algo mucho más desordenado (vea X11 Xt); esa complejidad esencial sigue ahí, sin el marco que sobresale de maneras horribles. Use la herramienta adecuada para el trabajo. Cuando un practicante no calificado usa la herramienta incorrecta, ¿culpas al lenguaje o al practicante?
Liudvikas Bukys
@aseq "Pero creo que si una técnica es propensa a hacer que tanta gente la use incorrectamente, puede ser algo defectuosa". Mirar los números en bruto es engañoso porque las diferentes tecnologías atraen a un número diferente de profesionales. Los porcentajes serían algo más significativos, sin embargo, no están disponibles fácilmente. Además, las barreras de entrada y la estructura de los incentivos no tecnológicos excluyen a los profesionales de diferentes grados de calidad , por lo que incluso los porcentajes pueden no brindar una imagen completa.
dasblinkenlight
1
No veo cómo la programación funcional no es "estratégica". Es, en todo caso, mejor que OOP para escalas más grandes porque reduce el acoplamiento y la complejidad y le permite trabajar en un nivel más alto de abstracción. Además, hay algunas técnicas muy buenas para construir interfaces de usuario de una manera puramente funcional: consulte "programación reactiva funcional".
Tikhon Jelvis
4

Haga una programación funcional, será una muy buena experiencia para usted, incluso si decide no continuar. Como puede leer en algunas de las respuestas aquí, muchas personas ni siquiera saben lo que es.

Los conceptos de lenguajes funcionales, por ejemplo, evaluación perezosa y transparencia referencial, son muy, muy buenos para aprender. Especialmente si te gusta la recursividad.

por ejemplo:

lenth :: [a] -> Integer
length (x:xs) = 1+length(xs)
length [] = 0

es una función haskell muy simple que se repite a través de una lista y calcula la longitud. Si está interesado en números más grandes que largos y desea usar Listas infinitas y otras cosas elegantes, pruebe la programación funcional.

Baarn
fuente
2
También es una forma estúpida de implementar (recorrer manualmente en lugar de usar abstracciones preconstruidas e ineficaz) length. Una forma diferente (más eficiente y más cercana a cómo se escriben realmente los programas FP no triviales) podría llamar a algunos pliegues con valor de inicio 0y función de paso acc -> acc + 1. Alternativamente, se sum . map (const 1)lee bien.
1
@Giorgio No, la función no es recursiva de cola. E incluso si lo fuera, en idiomas como Haskell que solo están relacionados tangiblemente con la eficiencia y el uso de la pila (uno tiene que evitar construir grandes troncos; ni esto ni lo lengthconstruido encima de los no estrictos foldhacen esto).
2
@ Jordania: Excepto que en Haskell, los valores no se pueden modificar y no todas las listas tienen una longitud (finita).
Jon Purdy
3
@ WalterMaier-Murdnelch Sí, la lista tendrá que ser atravesada eventualmente y uno debe entender lo que sucede debajo del capó. Pero eso no hace que las abstracciones sean inútiles, sino todo lo contrario. Podría escribir consultas SQL (sobre Yesod persistent), manejo de errores (sobre Maybe/ Either), malabarismo de estado (sobre State), recorridos de árbol (sobre Map/ Set), etc. pero describir mi intención en términos de funcionalidad de nivel superior es mejor en casi todos los sentidos y, por lo tanto, también lo que hace FP en la práctica.
1
@Giorgio En lenguajes estrictos, que siguen siendo la norma, lo es, aunque también depende del compilador que se encargue de esta optimización (Python, a pesar de algunos mitos urbanos, no es un lenguaje muy funcional y no optimiza las llamadas de cola - Lua OTOH lo hace). Pero tan pronto como se vuelve no estricto (ejemplo más destacado: Haskell), las reglas cambian. Puede ser recursivo de la cola y aún así obtener un desbordamiento de la pila porque ha construido un gran thunk (un millón de adiciones enteras apiladas diferidas debido a la pereza), o (sin cola) recurren salvajemente y se llevan bien. Entonces no tomaría esta regla como evangelio.
2

Como otros han dicho, la orientación a objetos es el paradigma dominante en la industria. Usted ha dicho que ha trabajado principalmente con programas que pueden ser abordados por un puñado de clases, pero en una aplicación industrial hay cientos o miles de casos de uso que deben abordarse y la orientación a objetos ha demostrado ser muy confiable. y una forma ampliamente comprensible de estructurar bases de código tan grandes.

Hablas de programación funcional, que es un competidor sólido para The Next Big Paradigm, pero FP aún no está familiarizado en la industria. Especialmente como usted es un programador de C ++, debe saber que la industria puede ser conservadora y que el mundo de C / C ++, con su énfasis en el rendimiento, es un lugar donde la naturaleza imperativa del hardware se considera una consideración muy real. En general, los programadores de sistemas integrados son extremadamente escépticos de FP, en mi experiencia.

Incluso si FP se convierte en un paradigma más dominante en la industria, es cierto que tendrá éxito en forma de lenguajes híbridos con función de objeto como F # y Scala y no en forma de lenguajes FP "puros" como Haskell.

Todo lo cual significa que sí, las "cosas" orientadas a objetos son importantes para las bases de códigos profesionales y su carrera.

Larry OBrien
fuente
2

OO ganó tracción porque fue una gran mejora para manejar la complejidad, como antes también lo era la programación estructurada / procesal.

Los beneficios de usar OO aumentan a medida que aumenta el tamaño del proyecto. Para un programa 1KLOC, no importa mucho qué paradigma use, todos ellos funcionarán bien. Pero para un programa 200KLOC +, simplemente no hay competencia viable para OO. Eso no significa que no pueda escribir un programa 200KLOC en C, solo que tendrá que ser mucho más disciplinado para evitar terminar con un desastre que nadie (ni siquiera usted) puede entender. Eso no significa que OO evitará tal desorden, solo que te facilitará la vida para evitarlo.

La programación funcional es un paradigma que se desvió en cierta medida del patrón anterior, porque no vino a ayudar a manejar aún más complejidad que OO, sino a abordar un tipo diferente de problemas: la programación paralela. Esa fue la primera vez, también, que un paradigma de programación intentó hacerlo: todos los mecanismos que existían antes en OO y / o SP / PP no eran parte del paradigma, sino solo entidades del sistema operativo (hilos, mutexes, etc.) encapsulado de acuerdo con las reglas del paradigma.

En ese sentido, la PF es mucho más natural que las otras, pero eso tiene el costo de revertir la forma en que generalmente pensamos sobre los problemas. Y debido a eso, tiene una capacidad limitada para manejar la misma complejidad a la misma escala que OO.

Supongo que esto limitará la adopción de FP en el futuro cercano a sistemas muy especializados, en general, secciones no muy grandes o especializadas de sistemas más grandes. Y el resto aún se hará con OO. Cuál de los que planea desarrollar (o aprender sobre el desarrollo) determinará cuál debería ser su enfoque de aprendizaje, IMO.

Fabio Ceconello
fuente
1

Aunque he usado mucho la programación genérica, las plantillas, etc.

Podría decirse que las plantillas son simplemente una forma diferente de OOP. Las funciones virtuales y la herencia explícita tienen un caso de uso específico, tiempo de ejecución, intercambiabilidad binaria. Las plantillas son intercambiables en tiempo de compilación. Sin embargo, en el nivel más básico, ofrecen la misma abstracción de características sobre cualquier tipo que ofrezca la interfaz correcta. El uso excesivo de la herencia en tiempo de ejecución es un olor de código significativo, y en este caso, estoy de acuerdo con usted, simplemente no es necesario durante la mayor parte del tiempo.

template<typename T> void func(T t) { t(5); }
void func(std::function<void(int)> t) { t(5); }

Estos dos fragmentos son efectivamente idénticos, aunque uno usa plantillas exclusivamente y el otro usa herencia en tiempo de ejecución y clases como su implementación. Ambos resumen sobre la función que estás llamando. Esta es trivialmente obvio cuando sustituyes Tpara std::function<void(int)>, por ejemplo. La única diferencia es el momento en que se hace esa abstracción. La versión de la plantilla es excelente para las funciones, y std::functiongeneralmente es mejor como variables miembro. No desea tener que crear una nueva clase cada vez que desea una nueva devolución de llamada.

OOP no es particularmente adecuado para algoritmos. Está más destinado a construcciones a gran escala, desglosando las piezas del programa. Si está escribiendo un algoritmo específico que opera en datos específicos, entonces es poco probable que necesite clases.

Es fácil y genial componer algoritmos de funciones. Sin embargo, tan pronto como superas eso, las clases emergen como el método dominante.

DeadMG
fuente
99
¡Guauu! Las plantillas son una "forma de OOP"? ¡Me alegraste el día, amigo!
SK-logic
44
Las plantillas son para programación genérica. No creo que sea correcto decir que las plantillas son simplemente una forma diferente de OOP. Espero que Alex Stepanov no esté leyendo esto :)
Yavar
Como he demostrado, las dos funciones son efectivamente equivalentes y tienen la misma abstracción. Simplemente ocurre en un momento diferente.
DeadMG
44
La comunidad C ++ de hoy usa metaprogramación de plantillas para cosas que se hicieron anteriormente de una manera más orientada a objetos. Sin embargo, no llamaría a esto "una forma diferente de OOP". Especialmente el ejemplo anterior lo llamaría "una forma en C ++ de usar objetos functor como una forma especial de programación funcional", que no es una solución típica de OOP.
Doc Brown
44
Se superponen en algunas características, correcto. Eso es porque ambos son útiles, por lo que inevitablemente hay algunas cosas que ambos hacen bien. Pero eso no muestra que sean isomórficos todo el tiempo, y no muestra que sean igualmente útiles (por ejemplo, sucintos y eficientes) para todos los problemas. Una lista vinculada puramente funcional también comparte algunas características con matrices dinámicas y sobreasignadas: ambas son colecciones ordenadas, se pueden crear de forma incremental con una complejidad razonable, admiten el uso de tipo pila (push / pop / peek), etc. pero difieren ampliamente, conceptualmente y en numerosas aplicaciones reales.
1

Sí, es importante, por esta única razón: comprender OOP te convierte en un mejor programador. Como regla general: la comprensión siempre te convierte en un mejor programador.

Cabe señalar que ni is-a, ni las clases, y mucho menos la herencia, tienen algo que ver con OOP. De lo que se trata realmente OOP es del desacoplamiento a través de la indirección, según lo formulado por el principio de inversión de dependencia . Se puede argumentar que este también es un aspecto importante de la PF. Si estudia tanto OOP como FP, se dará cuenta cada vez más de que en realidad son dos lados de un continuo. Cuanto más amplio y profundo lo entiendas, mejor serás.

Para comprender OOP, pruebe Io y quizás Smalltalk y Ruby.

back2dos
fuente
0

En el mundo del desarrollo, los lenguajes son herramientas, los paradigmas de programación son herramientas y las bibliotecas son herramientas. Cuantas más herramientas tenga, mejor podrá seleccionar la herramienta adecuada para el trabajo. Entonces eso argumentaría para que usted aprenda la programación OO, AOP y funcional, según lo permita el tiempo.

El mundo del desarrollo sigue creciendo más y más (en términos de lenguajes, marcos, etc.), por lo que no puede esperar aprender todo. Sin embargo, el objetivo de todas estas innovaciones es ayudar a los desarrolladores a ser más productivos (velocidad de desarrollo y reutilización) y hacer que el código sea más fácil de mantener (facilidad de comprensión, facilidad de extensión y modificación).

Lo mejor que puede hacer es hacer un aprendizaje continuo y dirigido, con la esperanza de que algo nuevo que acaba de aprender lo ayude a completar algo mejor y más rápido de una manera que nunca esperó.

Sam Goldberg
fuente
-1

He estado leyendo el libro de Steve Jobs y hay una historia sobre cómo Steve vio SmallTalk en los laboratorios Xerox PARC. Ese fue uno de los primeros idiomas OO. Sin OO hubiera sido horrendo desarrollar algo como una interfaz gráfica de usuario (GUI). Con toda la entrada asincrónica y poder saltar de una tarea a otra mientras trabaja con un "Objeto" u otro.

Entonces, si bien puedes hacer mucho con un lenguaje funcional y definitivamente tiene sus casos de uso. Cuando comienzas a lidiar con sistemas más complejos que interactúan más con problemas del mundo real, encuentras que OO es un diseño superior.

Bill Leeper
fuente
El primer marco de Macintosh GUI (Toolbox) fue un horrible pantano de C que hace que Win32 parezca cuerdo en comparación. ¡OO no entró en el mundo Mac hasta el cambio a OSX! Esta es una analogía terrible e históricamente engañosa en el mejor de los casos. Wings3D está escrito en Erlang y tiene una interfaz gráfica de usuario muy rica y es casi como el "mundo real", caso de uso complejo y práctico que puede obtener.
Reforza cómo la programación funcional no era adecuada, entonces no es así. (Todavía no he terminado el libro, interesante porque no eligieron usar uno de los muchos avances que el equipo de Xerox tenía, parecía que el equipo de Xerox estaba muy por delante de su tiempo)
Bill Leeper
Te das cuenta de que Erlang es un lenguaje funcional y Wings3D es una interfaz gráfica de usuario muy avanzada y complicada que contradice tu afirmación de que la programación funcional no es práctica y OO es mejor, que no lo es, a menos que no comprendas la teoría funcional.