oop - lenguajes - programacion orientada a objetos pdf
¿La programación procesal tiene alguna ventaja sobre OOP? (22)
"El problema con los lenguajes orientados a objetos es que tienen todo este entorno implícito que llevan consigo. Querías un plátano, pero lo que obtuviste era un gorila con el plátano y toda la jungla". -Joe Armstrong
¿Quieres la jungla?
[Editar:] Anteriormente pregunté esto como una pregunta quizás mal enmarcada sobre cuándo usar OOP versus cuándo usar la programación de procedimiento - algunas respuestas implicaban que estaba pidiendo ayuda para entender OOP. Por el contrario, he usado OOP mucho pero quiero saber cuándo utilizar un enfoque de procedimiento. A juzgar por las respuestas, considero que existe un consenso bastante sólido de que OOP es generalmente un mejor enfoque general, pero que se debe usar un lenguaje de procedimiento si la arquitectura OOP no proporcionará ningún beneficio de reutilización a largo plazo.
Sin embargo, mi experiencia como programador de Java ha sido diferente. Vi un programa Java masivo que diseñé reescrito por un gurú de Perl en 1/10 del código que había escrito y aparentemente tan robusto como mi modelo de perfección OOP. Mi arquitectura vio una cantidad significativa de reutilización y, sin embargo, un enfoque de procedimiento más conciso había producido una solución superior.
Entonces, a riesgo de repetirme, me pregunto en qué situaciones debería elegir un procedimiento sobre un enfoque orientado a objetos. ¿Cómo identificaría de antemano una situación en la que una arquitectura OOP es probable que sea excesiva y un enfoque de procedimiento más conciso y eficiente.
¿Alguien puede sugerir ejemplos de cómo se verían esos escenarios?
¿Cuál es una buena manera de identificar de antemano un proyecto que sería mejor atendido por un enfoque de programación de procedimiento?
Aquellos que apoyan religiosamente OOP no tienen ningún hecho para justificar su apoyo, como vemos aquí en estos comentarios también. Se les capacita (o se les lava el cerebro) en las universidades para usar y elogiar solamente OOP y OOP y es por eso que lo apoyan ciegamente. ¿Han hecho algún trabajo real en PP en absoluto? Aparte de proteger código de programadores descuidados en un entorno de equipo, OOP no ofrece mucho. Personalmente trabajando tanto en PP como en OOP durante años, encuentro que PP es simple, directo y más eficiente, y estoy de acuerdo con los siguientes sabios:
(Referencia: http://en.wikipedia.org/wiki/Object-oriented_programming ):
Varios investigadores y programadores reconocidos han criticado a OOP. Aquí hay una lista incompleta:
Luca Cardelli escribió un trabajo titulado "Propiedades de ingeniería malas de lenguajes orientados a objetos".
Richard Stallman escribió en 1995, "Agregar OOP a Emacs no es claramente una mejora; Usé OOP cuando trabajo en los sistemas de ventanas de Lisp Machine, y no estoy de acuerdo con la opinión habitual de que es una forma superior de programar ".
Un estudio de Potok et al. no ha mostrado diferencias significativas en la productividad entre la POO y los enfoques de procedimiento.
Christopher J. Date afirmó que la comparación crítica de OOP con otras tecnologías, relacional en particular, es difícil debido a la falta de una definición acordada y rigurosa de OOP. Se propone una base teórica en OOP que utiliza OOP como un tipo de sistema de tipo personalizable para admitir RDBMS.
Alexander Stepanov sugirió que OOP proporciona un punto de vista matemáticamente limitado y lo llamó "casi tan engañoso como la Inteligencia Artificial" (posiblemente refiriéndose a los proyectos de Inteligencia Artificial y mercadotecnia de la década de 1980 que a veces se consideran excesivamente celosos en retrospectiva).
Paul Graham ha sugerido que el propósito de OOP es actuar como un "mecanismo de pastoreo" que mantiene a los programadores mediocres en organizaciones mediocres "haciendo demasiado daño". Esto es a costa de frenar a los programadores productivos que saben cómo usar técnicas más potentes y compactas.
A Joe Armstrong, el principal inventor de Erlang, se le atribuye la siguiente afirmación: "El problema con los lenguajes orientados a objetos es que tienen todo este entorno implícito que llevan consigo. Querías un plátano, pero lo que obtuviste era un gorila sosteniendo el plátano y toda la jungla ".
Richard Mansfield, autor y ex editor de COMPUTE! la revista afirma que "como innumerables otras modas intelectuales a través de los años (" relevancia ", comunismo," modernismo ", etc.) la OOP estará con nosotros hasta que la realidad se afirme. Pero teniendo en cuenta cómo OOP actualmente impregna tanto a las universidades como a los lugares de trabajo, OOP podría ser un delirio duradero. Generaciones enteras de programadores adoctrinados continúan marchando fuera de la academia, comprometidos con OOP y nada más que OOP por el resto de sus vidas ", y también se cita diciendo que" OOP es escribir un programa, lo que pasa por la seguridad aeroportuaria es volar ".
Considere este escenario: su código no es OO. Tiene estructuras de datos y muchas funciones en su programa que operan en las estructuras de datos. Cada función toma una estructura de datos como parámetro y hace cosas diferentes dependiendo de un campo "tipo_de_datos" en la estructura de datos.
SI todo está funcionando y no va a cambiar, ¿a quién le importa si es OO o no? Esta funcionando. Está hecho. Si puede llegar a ese punto escribiendo más rápido procesalmente, entonces tal vez ese sea el camino a seguir.
Pero, ¿estás seguro de que no va a cambiar? Digamos que es probable que agregue nuevos tipos de estructuras de datos. Cada vez que agrega un nuevo tipo de estructura de datos en el que desea que funcionen esas funciones, debe asegurarse de encontrar y modificar cada una de esas funciones para agregar un nuevo caso "else if" para verificar y agregar el comportamiento que desea. para afectar el nuevo tipo de estructura de datos. El dolor de esto aumenta a medida que el programa se hace más grande y más complicado. Cuanto más probable es esto, mejor será el enfoque OO.
Y, ¿estás seguro de que está funcionando sin errores? Una lógica de conmutación más complicada crea más complejidad al probar cada unidad de código. Con llamadas a métodos polimórficos, el lenguaje maneja la lógica de conmutación para usted y cada método puede ser más simple y más fácil de probar.
Creo que Grady Booch dijo una vez que realmente empiezas a beneficiarte mucho con OOP con más de 10000 líneas de código.
Sin embargo, siempre iría por el camino correcto. Incluso para 200 líneas. Es un enfoque superior a largo plazo, y la sobrecarga es solo una excusa sobrevalorada. Todas las grandes cosas comienzan pequeñas.
Creo que deberías usar el estilo de procedimiento cuando tienes un problema muy bien especificado , la especificación no cambiará y quieres un programa muy rápido para ejecutarlo. En este caso, puede cambiar el mantenimiento por el rendimiento.
Por lo general, este es el caso cuando escribes un motor de juego o un programa de simulación científica . Si su programa calcula algo más de un millón de veces por segundo, debería optimizarse hasta el límite.
Puede usar algoritmos muy eficientes pero no será lo suficientemente rápido hasta que optimice el uso de la memoria caché. Puede ser un gran aumento de rendimiento tus datos están en caché. Esto significa que la CPU no necesita recuperar bytes de la RAM, los conoce. Para lograr esto, debe tratar de almacenar sus datos cerca el uno del otro, el tamaño del archivo ejecutable y de datos debe ser mínimo, e intente utilizar punteros menos que pueda (use arrays estáticos globales de tamaño fijo donde pueda pagar).
Si utiliza punteros, salta continuamente en la memoria y su CPU necesita volver a cargar el caché cada vez. El código OOP está lleno de punteros: cada objeto se almacena por su dirección de memoria. Llamas a alguien new
todas partes, lo que expande tus objetos por toda la memoria, haciendo que la optimización de la caché sea casi imposible (a menos que tengas un asignador o un recolector de basura que mantenga las cosas cerca unas de otras). Llama a callbacks y funciones virtuales. El compilador generalmente no puede alinear las funciones virtuales y una llamada a función virtual es relativamente lenta (salta al VMT, obtiene la dirección de la función virtual, llámala [esto implica presionar los parámetros y las variables locales en la pila, ejecutando la función luego haciendo estallar todo]). Esto es muy importante cuando tiene un ciclo que va de 0 a 1000000 25 veces en cada segundo. Al usar estilo de procedimiento no hay función virtual y el optimizar puede alinear todo en esos bucles.
Creo que el principio DRY (Do not Repeat Yourself) combinado con un poco de Agile es un buen enfoque. Construya su programa gradualmente comenzando con lo más simple que funcione, luego agregue características una a una y vuelva a factorizar su código según sea necesario a medida que avanza.
Si te encuentras escribiendo las mismas líneas de código una y otra vez, tal vez con datos diferentes, es hora de pensar en abstracciones que pueden ayudar a separar las cosas que cambian de las cosas que se mantiene igual.
Cree minuciosas pruebas unitarias para cada iteración para que pueda volver a factorizar con confianza.
Es un error dedicar demasiado tiempo tratando de anticipar qué partes de tu código deben ser reutilizables. Pronto se hará evidente una vez que el sistema comience a crecer en tamaño.
Para proyectos más grandes con múltiples equipos de desarrollo concurrentes, necesitas tener algún tipo de plan arquitectónico para guiar el desarrollo, pero si trabajas solo o en un pequeño equipo cooperativo, la arquitectura surgirá naturalmente si te apegas al principio DRY.
Otra ventaja de este enfoque es que haga lo que haga se basa en la experiencia del mundo real. Mi analogía favorita: tienes que jugar con los ladrillos antes de que puedas imaginar cómo se podría construir el edificio.
Creo que la idoneidad de OOP depende más del área temática en la que trabajas que del tamaño del proyecto. Hay algunas áreas temáticas (CAD, modelado de simulación, etc.) en las que OOP se relaciona naturalmente con los conceptos involucrados. Sin embargo, hay muchos otros dominios donde el mapeo termina siendo torpe e incongruente. Muchas personas que usan OOP para todo parecen pasar mucho tiempo tratando de clavar clavijas cuadradas en agujeros redondos.
OOP tiene su lugar, pero también lo hacen la programación de procedimientos, la programación funcional, etc. Mire el problema que está tratando de resolver, luego elija un paradigma de programación que le permita escribir el programa más simple posible para resolverlo.
En mi humilde opinión, los beneficios a largo plazo de OOP superan el tiempo ahorrado en el corto plazo.
Como dijo AZ, usar OOP de forma procedimental (lo cual hago bastante), es una buena forma de hacerlo (para proyectos más pequeños). Cuanto más grande sea el proyecto, más OOP deberías emplear.
La mayoría de los estudios han encontrado que el código OO es más conciso que el código de procedimiento. Si observa proyectos que reescribieron el código C existente en C ++ (algo que no aconsejo necesariamente, por cierto), normalmente verá reducciones en el tamaño del código de entre 50 y 75 por ciento.
Entonces la respuesta es - ¡siempre use OO!
La reutilización (o la falta de ella) no está ligada a ningún paradigma de programación específico. Use programación orientada a objetos, de procedimiento, funcional o cualquier otra programación según sea necesario. La organización y la reutilización provienen de lo que haces, no de la herramienta.
Los dos conceptos no son mutuamente excluyentes, es muy probable que use PP junto con OOP, no puedo ver cómo segregarlos.
Los programas de procedimiento pueden ser más simples para cierto tipo de programa. Por lo general, estos son los programas cortos de tipo script.
Me gustan Glass'' reglas de Glass'' de 3 cuando se trata de reutilización (que parece ser lo que le interesa).
1) Es 3 veces más difícil construir componentes reutilizables como componentes de un solo uso
2) Se debe probar un componente reutilizable en tres aplicaciones diferentes antes de que sea lo suficientemente general como para aceptarlo en una biblioteca de reutilización
De esto creo que puedes extrapolar estos corolarios
a) Si no tiene el presupuesto por 3 veces el tiempo que le llevaría construir un componente de uso único, tal vez debería detener la reutilización. (Asumiendo dificultad = tiempo)
b) Si no tiene 3 lugares donde usaría el componente que está construyendo, tal vez debería evitar la construcción del componente reutilizable.
Sigo pensando que OOP es útil para construir el componente de uso único, porque siempre puede refactorizarlo en algo que sea realmente reutilizable más adelante. (También puede refactorizar desde PP a OOP, pero creo que OOP ofrece suficientes beneficios en cuanto a organización y encapsulado para comenzar allí)
Mis dos centavos...
Ventajas de la programación de procedimientos
- Diseño simple (prueba rápida de concepto, batalla con requisitos dramáticamente dinámicos)
- Comunicaciones simples entre proyectos
- Natural cuando el orden temporal importa
- Menos sobrecarga en tiempo de ejecución
Cuanto más se vuelva bueno el código de procedimiento, más cerca estará de Funcional. Y las ventajas de FP son bien conocidas.
Parte de tu respuesta depende del idioma que estés usando. Sé que en Python, es bastante simple mover el código de procedimiento a una clase, o un objeto más formal.
Una de mis heurísticas se basa en cómo es el "estado" de la situación. Si el procedimiento contamina el espacio de nombres, o podría afectar el estado global (de una manera mala o impredecible), encapsular esa función en un objeto o clase probablemente sea prudente.
Puede escribir mal software en ambos conceptos. Sin embargo, el software complejo es mucho más fácil de escribir, comprender y mantener en los lenguajes OO que en los procedimientos. Escribí aplicaciones ERP altamente complejas en lenguaje de procedimientos (Oracle PL / SQL) y luego cambié a OOP (C #). Fue y sigue siendo un soplo de aire fresco.
Si "piensas OO" cuando estás programando, entonces no estoy seguro de que tenga sentido preguntar "¿cuándo debería volver a la programación de procedimientos?" Esto es equivalente a preguntarle a los programadores de Java qué no pueden hacer tan bien porque Java requiere clases. (Lo mismo ocurre con los lenguajes .NET).
Si tiene que hacer un esfuerzo para dejar de pensar en el procedimiento, entonces le aconsejaría preguntar cómo puede superar eso (si lo desea); de lo contrario, quédate con el procedimiento. Si se requiere mucho esfuerzo para entrar en el modo OOP, su código OOP probablemente no funcionará muy bien de todos modos (hasta que llegue más lejos en la curva de aprendizaje).
Si el proyecto es tan pequeño que estaría contenido dentro de una clase y no se va a usar por mucho tiempo, consideraría usar funciones. Alternativamente, si el idioma que está utilizando no es compatible con OO (por ejemplo, c).
Siempre empiezo a diseñar de forma descendente y en las partes superiores es mucho más fácil pensar en términos de OOP. Pero cuando llega el momento de codificar algunas piezas específicas, es mucho más productivo con la programación de procedimientos. OOP es genial en el diseño y en la configuración del proyecto, de modo que se pueda aplicar el paradigma de divide e imperará. Pero no puedes aplicarlo en cada aspecto de tu código, como si fuera una religión :)
Sugeriría utilizar el enfoque más conciso y basado en estándares que pueda encontrar para cualquier problema en particular. Su colega que utilizó Perl demostró que un buen desarrollador que conoce bien una herramienta en particular puede lograr grandes resultados independientemente de la metodología. En lugar de comparar sus proyectos Java-versus-Perl como un buen ejemplo del debate de procedimiento versus OOP, me gustaría ver un enfrentamiento entre Perl y un lenguaje conciso similar como Ruby, que también tiene los beneficios de orientación del objeto. Ahora eso es algo que me gustaría ver. Mi suposición es que Ruby saldría ganando, pero no estoy interesado en provocar una guerra de llama del idioma aquí. Lo único que quiero decir es que eliges la herramienta adecuada para el trabajo; cualquier enfoque puede lograr la tarea de la manera más eficiente y robusta. manera posible. Java puede ser robusto debido a su orientación a objetos, pero a medida que usted, su colega y muchos otros que están convirtiéndose a lenguajes dinámicos como Ruby y Python están encontrando estos días, hay soluciones mucho más eficientes, ya sean de procedimiento o de OOP.
Tú mismo le diste la respuesta: los grandes proyectos simplemente necesitan OOP para evitar que se vuelvan demasiado complicados.
Desde mi punto de vista, la mayor ventaja de OOP es la organización de código. Esto incluye los principios de DRY y encapsulación.
Uno de los objetivos de OOP era facilitar la reutilización, aunque no es el único. La clave para aprender a usar objetos de manera efectiva es Patrones de diseño.
Todos estamos acostumbrados a la idea de algoritmos que nos dicen cómo combinar diferentes procedimientos y estructuras de datos para realizar tareas comunes. A la inversa, observe los patrones de diseño de la pandilla de los cuatro para obtener ideas sobre cómo combinar objetos para realizar tareas comunes.
Antes de aprender sobre Patrones de diseño, estaba bastante en la oscuridad acerca de cómo usar objetos de manera efectiva, excepto como una estructura de super tipo.
Recuerde que la implementación de Interfaces es tan importante, si no más importante, que la herencia. En el pasado, C ++ era el principal ejemplo de programación orientada a objetos y el uso de interfaces se oscurecía en comparación con la herencia (funciones virtuales, etc.). El legado de C ++ significaba que se ponía mucho más énfasis en la reutilización del comportamiento en los diversos tutoriales y las amplias descripciones. Desde entonces, Java, C # y otros lenguajes han movido la interfaz a un mayor enfoque.
Para qué interfaces es ideal definir exactamente cómo dos objetos interactúan con cada uno. No se trata de reutilizar el comportamiento. Como resultado, gran parte de nuestro software se trata de cómo interactúan las diferentes partes. Entonces, el uso de la interfaz proporciona una mayor ganancia de productividad que tratar de fabricar componentes reutilizables.
Recuerde que al igual que muchas otras ideas de programación, los objetos son una herramienta. Deberá usar su mejor criterio para determinar qué tan bien funcionan para su proyecto. Para mi software CAD / CAM para máquinas de corte de metal, existen funciones matemáticas importantes que no se colocan en objetos porque no hay ninguna razón para que estén en objetos. En cambio, están expuestos desde la biblioteca y utilizados por el objeto que los necesita. Luego hay algunas funciones matemáticas que se hicieron orientadas a objetos ya que su estructura conduce naturalmente a esta configuración. (Tomando una lista de puntos y transformándola en varios tipos diferentes de rutas de corte). Nuevamente use su mejor juicio.