Relación entre orientación a objetos y algoritmos.

9

Mientras leo algunos libros de texto de algoritmos, están llenos de procedimientos inteligentes para algunos problemas (clasificación, ruta más corta) o algunos métodos generales (algoritmos recursivos, división y conquista, programación dinámica ...). Encontré pocos rastros de programación orientada a objetos allí; (¿Por qué están más orientados a los procedimientos?).

Entonces estaba pensando:

  • ¿Cuál es la relación entre algoritmos y OOP? ¿Son dos temas independientes?
  • ¿Hay algunos problemas que solo pueden ser presentados y resueltos por OOP?
  • ¿Cómo puede ayudar OOP a los algoritmos? ¿O en qué dirección puede afectarlo?
Ahmad
fuente
44
No es un duplicado, pero programmers.stackexchange.com/questions/239045/…
Doc Brown
@DocBrown Gracias, fue muy útil, sin embargo, aquí podemos considerar algunos conceptos en torno a la OO, como la herencia, el polimorfismo ...
Ahmad
1
"¿Por qué los libros de texto de algoritmos están más orientados a los procedimientos?" Java también está orientado a procedimientos. Java es un lenguaje procesal orientado a objetos.
Pieter B
1
@gnat Modifiqué mi pregunta, no sé si esa explicación fue necesaria o buena o no. Sin embargo, admito que la pregunta abordada por Doc Brown posee más respuestas relacionadas con mis inquietudes.
Ahmad

Respuestas:

10

Primero, definamos qué entendemos por OOP. Por OOP me refiero principalmente a:

  • Encapsulación y ocultación de detalles en clase.
  • Polimorfismo de comportamiento a través de herencia y métodos virtuales.

Ahora para responder a tu pregunta:

¿Cuál es la relación entre algoritmos y OOP? ¿Son dos temas independientes?

Si.

¿Hay algunos problemas que solo pueden ser presentados y resueltos por OOP?

No. OOP primario ofrece conveniencia y capacidad de razonar sobre el código para el programador. No aumenta tu poder expresivo.

¿Cómo puede ayudar OOP a los algoritmos? ¿O en qué dirección puede afectarlo?

Como dije anteriormente. Ambos puntos describí OOP como se aplican aquí. Poder ocultar detalles de algoritmos y sus estructuras de datos puede ayudar a razonar sobre todo el asunto. Muchos algoritmos contienen detalles con los que no desea que el usuario de ese algoritmo juegue. Ocultar esos detalles ayuda mucho.

La capacidad de tener un comportamiento polimórfico también es genial. Listse define como poder agregar / eliminar / borrar los elementos en cualquier lugar de la colección. Pero puede implementarse como una matriz redimensionable, doble o simple, etc. Tener una única API para múltiples implementaciones puede ayudar a reutilizar.

¿Por qué los libros de texto de algoritmos están más orientados a los procedimientos?

Como dije, OOP no es necesario para implementar un algoritmo. Además, muchos algoritmos son antiguos y se crearon cuando OOP aún no estaba muy extendido. Por lo tanto, también podría ser algo histórico.

Eufórico
fuente
1
A pesar de la antigüedad de los textos, es probable que no desee enturbiar el agua de un algoritmo con OOP, simplemente porque es moderno.
Gusdor
15

Los algoritmos y OOP son dos términos dispares, que solo tienen en común, que son términos CS . Simplemente: un algoritmo es como una receta de cocina : para hacer x necesitas los siguientes ingredientes y hacer el paso 1, 2, 3, 4, 5, 6 ... entonces tienes tu comida preparada.

Dicho esto, parece natural que los algoritmos se describan de manera procesal . Procedimiento significa nada más que: primero haz xy luego haz y .

Un problema común es: »¿Cómo ordenar un conjunto de x ?«. Una solución fácil de entender es bubble-sort:

  1. Itere sobre el conjunto desde el último elemento siempre que no haya alcanzado el primer elemento y mientras itera
  2. Inicie una segunda iteración desde el principio hasta el elemento actual de la primera iteración y
  3. Compare el elemento actual de (2) con su sucesor
  4. Si es mayor, intercambie posiciones

Esa es la descripción algorítmica / verbal del bubblesortalgoritmo.

Aquí viene una implementación de procedimiento / pseudocódigo

bubbleSort(Array A)
  for (n=A.size; n>1; n=n-1){
    for (i=0; i<n-1; i=i+1){
      if (A[i] > A[i+1]){
        A.swap(i, i+1)
    } 
  } 
}

Eso fue fácil.

¿Cómo se relaciona eso con OOP ? Podría usar este algoritmo para tratar colecciones (un objeto en sí mismo) de objetos :

Ejemplo en Javascript (aunque no tiene una OO-Lingo limpia , pero es casi inexistente y fácil de entender)

objects =[{"name":"Peter"}, {"name":"Paul"}, {"name":"Mary"}]

compareObjects=function(x,y){ return x.name>y.name };

sorted = objects.sort(compareObjects)

console.log(sorted)

Tenemos a) una colección objects, b) un método común a esta colección sortque contiene / extrae el algoritmo de clasificación yc) nuestros objetos Peter , Paul y Mary . La especificación para la clasificación se encuentra aquí .

¿Cuál es la relación entre algoritmos y OOP? ¿Son dos temas independientes?

Por lo que se dijo, debería quedar claro, la respuesta debería ser: sí, son independientes.

¿Cómo puede ayudar OOP a los algoritmos? ¿O en qué dirección puede afectarlo?

OOP es solo un estilo de programación. No puede ayudar de ninguna manera. De lo contrario, se podría implementar un algoritmo en un lenguaje OO para hacer algo a los objetos (como se muestra)

¿Hay algunos problemas que solo pueden ser presentados y resueltos por OOP?

No puedo pensar en uno (pero eso no significa que sea imposible). Pero si lo mira al revés: OOP es útil, si desea modelar algunos problemas y resolverlos con un algoritmo apropiado. Digamos que tiene un registro de friendsque podría modelar como objectscon propertiesy si quieres una listde las friends ordenados de ninguna manera, se puede usar el ejemplo de código dado anteriormente para hacer exactamente eso.

¿Por qué los libros de texto de algoritmos están más orientados a los procedimientos?

Como se dijo: es más natural , ya que el procedimiento es el carácter de los algoritmos.

Thomas Junk
fuente
77
Esta respuesta presupone que los algoritmos son naturalmente procesales. Ciertamente, algunos de ellos lo son, pero existen algoritmos funcionales. La razón por la cual los libros de algoritmos son de procedimiento probablemente tenga más que ver con el hecho de que están enfocados en el rendimiento, por lo que depende del lector preocuparse por imponer abstracciones y porque los lenguajes imperativos son más populares que los lenguajes funcionales.
Doval
Creo que eso no está del todo bien. Cuando se habla de lenguajes de programación funcionales , se habla de la implementación , no del algoritmo en sí. Tomemos, por ejemplo, el quicksort wiki de Haskell.haskell.org/Introduction#Quicksort_in_Haskell Ambos estaríamos de acuerdo en que esta es una implementación funcional del quicksort-algortihm. Pero si describe lo que se hace, debe recurrir a un modo de descripción prodecural . Y a partir de esta descripción, podría implementar una implementación de procedimiento.
Thomas Junk
1
@ThomasJunk Usted no tiene que recurrir a un modo de procedimiento de la descripción, ya que una aplicación funcional dice lo que las cosas son , no una secuencia de pasos. ¿Cómo va a dar una descripción secuencial para una computación pura y perezosa? No sabe de antemano cuánto de una expresión se evaluará, ni en qué orden se calcularán sus subexpresiones.
Doval
2
Desafortunadamente, no tengo un título de CS, por lo que no tengo un amplio conjunto de habilidades para demostrar lo siguiente: pero creo que cada algoritmo podría describirse de una manera u otra, por lo que no existe un algoritmo funcional genuino puro. ¿No es eso lo que significa, en consecuencia, la integridad de la gira?
Thomas Junk
2
@Doval bien, ya que el propio Turing demostró que el cálculo lambda y las máquinas de Turing son equivalentes, entonces es obvio que todo lo que puedes decir de una manera funcional, puedes hacerlo imperativamente. También es trivial convertir la computación perezosa en una forma imperativa: el compilador de Haskell lo hace todo el tiempo ... Al final, es solo una cuestión de preferencia. A veces funcional es más adecuado, y a veces imperativo, y otras veces lógico es el mejor ...
AK_
5

tienes un problema.

El modelo de dominio comercial describe su problema, y ​​los conceptos del dominio del problema con el que va a estar lidiando.

Los algoritmos describen la forma en que va a resolver sus problemas, conceptualmente; ¿Cómo será su implementación? y cómo manejas tu problema después de traducirlo a términos de "Ciencias de la Computación".

El paradigma de programación, ya sea OOP, funcional, lógico, de procedimiento o incluso no estructurado, describe cómo estructurará su solución, qué forma adoptará, qué conceptos de "Ingeniería de software" va a emplear y cuáles " Teoría del lenguaje de programación "conceptos que va a emplear.

Para decirlo de manera más simple, los algoritmos describen en general su solución al problema ("Esto es lo que voy a hacer"). Mientras que el paradigma de programación se ocupa de su implementación real ("Así es como lo voy a hacer").

ALASKA_
fuente
Tenga en cuenta que de una manera posiblemente imperfecta, los lenguajes declarativos tienen como objetivo reducir o eliminar el paso "cómo". Su objetivo es que usted simplemente diga "esto es lo que quiero" (por ejemplo, escribiendo ecuaciones de alto nivel). Piense en una consulta SQL típica: muy poco de ella es "algorítmica"; simplemente le dice a la base de datos lo que desea, y depende de cómo maneje su solicitud (dentro de ciertas limitaciones, por supuesto).
Andres F.
4

Algoritmos = contar la historia " Cómo " (es decir, cómo manipular los datos de entrada utilizando estructuras de datos a tiempo para producir los resultados deseados)

OOP = una " Metodología " facilitada por los lenguajes OO para escribir programas (= algoritmos + estructuras de datos) que le brinda seguridad y abstracción de la memoria

OOP es solo un paradigma de implementación de algoritmos.

Buena analogía : películas

Puede grabar escenas empleando un especialista o no. El guión (algoritmo) no cambia. La gente no debería ver ninguna diferencia en el resultado final.

EDITAR: puede probar un MOOC de buena calidad: https://www.coursera.org/course/algs4partI que entrelaza los temas discutidos (especialmente el enfoque OOP) y le da la esencia de lo que pregunta aquí.

Marcin Wachulski
fuente
Realmente disfruté tu analogía de la película. Lo tomaré prestado en el futuro.
Marc LaFleur
2

Alexander Stepanov es el creador original de la Biblioteca de plantillas estándar de C ++ (STL), que es la biblioteca de algoritmos fundacional para C ++. C ++ es un lenguaje multi-paradigmático que incluye características "Orientadas a Objetos", pero Alexander Stepanov tiene esto que decir sobre la Orientación de Objetos:

http://www.stlport.org/resources/StepanovUSA.html

STL no está orientado a objetos. Creo que la orientación a objetos es casi tan engañosa como la Inteligencia Artificial. Todavía tengo que ver un código interesante que proviene de estas personas OO.

Encuentro la POO técnicamente poco sólida. Intenta descomponer el mundo en términos de interfaces que varían en un solo tipo. Para lidiar con los problemas reales, necesita álgebras de múltiples orígenes, familias de interfaces que abarcan varios tipos. Encuentro la POO filosóficamente falsa. Afirma que todo es un objeto. Incluso si es cierto, no es muy interesante: decir que todo es un objeto no dice nada en absoluto. Me parece que la OOP es metodológicamente incorrecta. Comienza con las clases. Es como si los matemáticos comenzaran con axiomas. No comienzas con axiomas, comienzas con pruebas. Solo cuando haya encontrado un montón de pruebas relacionadas, puede encontrar axiomas. Terminas con axiomas. Lo mismo es cierto en la programación: hay que comenzar con algoritmos interesantes. Solo cuando los entiendes bien,

Pasé años tratando de encontrar algún uso para la herencia y los virtuales, antes de entender por qué ese mecanismo era fundamentalmente defectuoso y no debería usarse.

Stepanov expresó su biblioteca de algoritmos no con objetos, sino con iteradores genéricos .

James Brock
fuente
Bueno, él está equivocado ... sobre todo porque el STL está muy orientado a objetos ... Orientado a objetos en el más moderno desde el término ...
AK_
1
@AK_ - No creo que esté equivocado en absoluto. STL ni siquiera es aproximadamente OO en ningún sentido del término. Puede traducir el STL directamente a un lenguaje no OO que tenga polimorfismo paramétrico (por ejemplo, Haskell o SML) sin necesidad de cambiarlo de manera sustancial.
Julio
2

Los algoritmos describen lo que debe hacer la computadora. La estructura describe cómo se presenta el algoritmo [en el código fuente]. OOP es un estilo de programación que aprovecha ciertas estructuras "orientadas a objetos".

Los libros de algoritmos a menudo evitan la POO porque se centran en el algoritmo, no en la estructura. Los fragmentos de código que dependen en gran medida de la estructura tienden a ser malos ejemplos para poner en un libro de algoritmos. Del mismo modo, los libros de OOP a menudo evitan los algoritmos porque desordenan la historia. El punto de venta de OOP es su fluidez, y vincularlo a un algoritmo lo hace parecer más rígido. Se trata más del enfoque del libro que de cualquier otra cosa.

En el código de la vida real, usará ambos lado a lado. No puede resolver problemas informáticos sin algoritmos, por definición, y le resultará difícil escribir buenos algoritmos sin estructura (POO o de otro modo).

Como ejemplo de dónde se difuminan, tome la Programación dinámica. En un libro de algoritmos, describiría cómo tomar un conjunto de datos homogéneo en una matriz y utilizar la Programación dinámica para llegar a una solución. En un libro de OOP, puede encontrarse con una estructura como Visitor, que es una forma de hacer algoritmos arbitrarios en un conjunto de objetos heterogéneos. El ejemplo del libro DP podría considerarse como un visitante muy simple que opera en objetos en un orden generalmente ascendente. El patrón Visitante podría considerarse como el esqueleto de un problema de DP, pero falta la carne y las papas. En realidad, encontrará que a menudo necesita ambos juntos: usa el patrón Visitor para tratar la heterogeneidad en su conjunto de datos (DP es malo en eso), y usa DP dentro de la estructura de Visitor para organizar su algoritmo para minimizar el tiempo de ejecución (Visitor no

También vemos algoritmos que funcionan sobre los patrones de diseño. Es más difícil redactar ejemplos en un espacio pequeño, pero una vez que tiene estructura, comienza a querer manipular esa estructura y utiliza algoritmos para hacerlo.

¿Hay algunos problemas que solo pueden ser presentados y resueltos por OOP?

Esta es una pregunta más difícil de responder de lo que piensas. Para el primer orden, no hay una razón computacional por la que necesite OOP para resolver cualquier problema. La prueba simple es que cada programa OOP se compila en ensamblador, que es un lenguaje decididamente no OOP.

Sin embargo, en el esquema general de las cosas, la respuesta comienza a ser tímida hacia sí. Raramente está limitado simplemente por las metodologías informáticas. La mayoría de las veces hay cosas como las necesidades comerciales y la habilidad del desarrollador que son factores que influyen en la ecuación. Muchas aplicaciones hoy en día no podrían escribirse sin OOP, no porque OOP sea de alguna manera fundamental para la tarea, sino porque la estructura proporcionada por OOP fue esencial para mantener el proyecto en buen camino y dentro del presupuesto.

Esto no dice que nunca abandonaremos OOP en el futuro por alguna nueva estructura divertida. Simplemente dice que es una de las herramientas más efectivas en nuestra caja de herramientas para una fracción sorprendentemente grande de tareas de programación que existen hoy en día. Los problemas futuros pueden hacer que nos acerquemos al desarrollo utilizando diferentes estructuras. Por un lado, espero que las redes neuronales requieran un enfoque de desarrollo muy diferente, que puede resultar o no "Orientado a Objetos".

No veo la desaparición de OOP en el futuro cercano debido a la forma en que piensan los diseñadores de algoritmos. Hasta la fecha, el patrón habitual es que alguien diseña un algoritmo que no aprovecha la POO. La comunidad OOP se da cuenta de que el algoritmo realmente no se ajusta a la estructura OOP, y realmente no es necesario, por lo que envuelven todo el algoritmo en una estructura OOP y comienzan a usarlo. Considere boost::shared_ptr. Los algoritmos de conteo de referencia que descansan en el interior shared_ptrno son muy amigables con la POO. Sin embargo, el patrón no se hizo popular hasta que se shared_ptrcreó un envoltorio de OOP a su alrededor que expuso las capacidades de los algoritmos en un formato estructurado de OOP. Ahora, es tan popular que se convirtió en la última especificación para C ++, C ++ 11.

¿Por qué es tan exitoso? Los algoritmos son excelentes para resolver problemas, pero a menudo requieren una inversión inicial sustancial en investigación para comprender cómo usarlos. El desarrollo orientado a objetos es muy efectivo para envolver dichos algoritmos y proporcionar una interfaz que requiere menos inversión inicial para aprender.

Cort Ammon
fuente
1

Además de las excelentes respuestas, mencionaré una comunidad conceptual adicional entre OOP y Algoritmos.

Tanto OOP como Algoritmos enfatizan fuertemente el uso de precondiciones y postcondiciones para asegurar la corrección del código.

En general, esta es una práctica estándar en todas las áreas de la informática; sin embargo, este principio rector da como resultado una ruta evolutiva en OOP que hace que sea mutuamente beneficioso implementar algoritmos en el entorno OOP.

En OOP, se puede crear un grupo de objetos que puedan satisfacer el mismo contrato (condiciones previas y condiciones posteriores) para implementar una interfaz. El usuario de dicha interfaz no necesitará saber qué implementación se usa en el objeto subyacente, excepto en algunas situaciones raras (en las que ocurre una abstracción con fugas).

Un algoritmo es una implementación de pasos utilizados para realizar un cálculo, uno que tomará la condición previa y producirá la condición posterior.

Por lo tanto, uno puede tomar prestada la idea de abstracción en forma de precondiciones y postcondiciones, y aplicarla a los algoritmos. Encontrará que a veces los algoritmos complicados pueden descomponerse en pasos más pequeños, y estos pasos más pequeños pueden permitir diferentes estrategias de implementación siempre que se cumplan las mismas condiciones previas y posteriores.

Al implementar algoritmos en OOP, uno puede hacer que estos pasos más pequeños sean intercambiables.

Finalmente, tenga en cuenta que FP y OOP no son mutuamente excluyentes. Cualquier cosa descrita anteriormente puede ser igualmente aplicable a FP también.

rwong
fuente
Gracias por el punto! Como dijiste si el algoritmo es solo algunos pasos, entonces OOP puede ayudarnos a proporcionar pasos más abstractos. Usted señaló sobre "implementar algoritmos en OOP", modifiqué mi pregunta para hacerla, ¿siempre es beneficiosa?
Ahmad
1
confunde OOP con "Diseño por contrato". Es muy útil sin OOP, y la mayoría de los lenguajes OOP (C #, Java) no brindan soporte real (admiten interfaces simples, no condiciones previas / posteriores)
AK_
1
@AK_ Estoy de acuerdo en que Diseño por contrato es el nombre correcto para la comunidad descrita en mi respuesta. Lo que estoy afirmando es que OOP como paradigma de diseño abraza fuertemente el Diseño por Contrato, solo lea cualquier libro de texto de OOP. Mi respuesta original también menciona que esta comunidad no es exclusiva de OOP.
rwong
-1
What is the relation between algorithms and OOP? Are they two independent topics?

Los algoritmos tratan sobre cómo resolver un problema (cómo generar resultados a partir de la entrada dada), OOP trata sobre cómo formular o expresar nuestra solución (los pasos del algoritmo).

Un algoritmo se puede describir en lenguaje natural o en lenguaje ensamblador, pero los conceptos que tenemos en un lenguaje natural nos ayudan a escribirlo y comprenderlo mejor. Por ejemplo, el algoritmo para ordenar burbujas podría ser:

bubbleSort(Array A)
  for (n=A.size; n>1; n=n-1){
    for (i=0; i<n-1; i=i+1){
      if (A[i] > A[i+1]){
        A.swap(i, i+1)
    } 
  } 
}

Para ocultar los detalles swapy relacionarlos con el A, utilizamos una sintaxis y función OOP, luego OO acerca el algoritmo a nuestro lenguaje natural y comprensión.

Are there some problems which can only be presented and solved by OOP?

No, si considera que cualquier programa (o algoritmo) en una computadora se traducirá a un conjunto de instrucciones ejecutadas en la CPU ( Turing Machine ) y si consideramos estas instrucciones como el último algoritmo que resuelve el problema en una computadora , entonces OOP No puedo hacer algo más. Simplemente lo acerca al entendimiento humano y al razonamiento. Es una forma de empaquetar nuestros procedimientos y estructuras de datos.

How OOP can help algorithms? Or in which direction it can affect it?

Puede ser útil establecer o formular un algoritmo más fácil o más comprensible. Puede ocultar detalles y proporcionar una visión general de la solución.

En teoría, el algoritmo es el primero y lo implementa el segundo . Pero en realidad, no podemos estar seguros de que nuestro algoritmo funcione como se espera hasta que lo rastreemos o generemos el resultado esperado. Las computadoras nos ayudan a hacer eso, pero no espera escribirlo en lenguaje de máquina (ensamblaje).

En este sentido, OOP facilita la implementación, prueba y refinamiento de nuestro algoritmo en computadoras y lo escribe para una computadora en un idioma cercano a nuestro lenguaje natural.

Ahmad
fuente