La programación orientada a objetos ( abreviado OOP) es una metodología de programación basada en representar un programa como un conjunto de objetos que interactúan , cada uno de los cuales es una instancia de una determinada clase , y las clases forman una jerarquía de herencia [1] .
Ideológicamente, OOP es un enfoque de la programación en cuanto al modelado de objetos de información, resolviendo en un nuevo nivel la tarea principal de la programación estructural : estructurar la información desde el punto de vista de la controlabilidad [2] , lo que mejora significativamente la controlabilidad del proceso de modelado. mismo, que, a su vez, es especialmente importante cuando se implementan grandes proyectos.
La manejabilidad de los sistemas jerárquicos implica minimizar la redundancia de datos (similar a la normalización ) y su integridad, por lo que lo que se crea convenientemente manejable también se entenderá convenientemente. Por lo tanto, a través de la tarea táctica de manejabilidad, se resuelve la tarea estratégica: traducir la comprensión de la tarea por parte del programador en la forma más conveniente para su uso posterior.
Los principios básicos de estructuración en el caso de OOP están relacionados con varios aspectos de la comprensión básica del tema, que se requiere para el manejo óptimo del modelo correspondiente:
Es decir, de hecho, estamos hablando de una organización progresiva de la información según criterios semánticos primarios: “importante/sin importancia”, “clave/detalles”, “padre/hijo”, “único/plural”. La progresión, en particular, en la última etapa permite pasar al siguiente nivel de detalle, que cierra el proceso general.
El lenguaje humano ordinario en su conjunto refleja la ideología de la OOP, comenzando con la encapsulación de la representación del objeto en la forma de su nombre y terminando con el polimorfismo de usar la palabra en sentido figurado, que finalmente desarrolla [3] el expresión de la representación a través del nombre del objeto a un concepto-clase completo.
Abstracción de datos Abstracción significa resaltar la información significativa y excluir la información irrelevante de la consideración. OOP solo considera la abstracción de datos (a menudo denominada simplemente "abstracción"), lo que implica un conjunto de las características más significativas de un objeto disponible para el resto del programa. Encapsulación [4] La encapsulación es una propiedad del sistema que le permite combinar datos y métodos que funcionan con ellos en una clase. Algunos lenguajes (como C++ , Java o Ruby ) equiparan la encapsulación con la ocultación , pero otros ( Smalltalk , Eiffel , OCaml ) distinguen entre los dos. Herencia [4] La herencia es una propiedad del sistema que le permite describir una nueva clase basada en una existente con funcionalidad parcial o totalmente prestada. La clase de la que hereda se denomina base, padre o superclase. La nueva clase es una clase descendiente, sucesora, secundaria o derivada. Polimorfismo de subtipo [4] El polimorfismo de subtipo (simplemente llamado "polimorfismo" en OOP) es una propiedad del sistema que permite que se utilicen objetos con la misma interfaz sin información sobre el tipo y la estructura interna del objeto. Otro tipo de polimorfismo, paramétrico , en programación orientada a objetos se denomina programación genérica . Clase Una clase es un tipo de datos universal y complejo , que consiste en un conjunto unificado temáticamente de "campos" (variables de tipos más elementales) y "métodos" (funciones para trabajar con estos campos), es decir, es un modelo de entidad de información con interfaces internas y externas para operar su propio contenido (valores de campo). En particular, las clases utilizan ampliamente bloques especiales de uno o más a menudo dos métodos emparejados responsables de operaciones elementales con un campo específico (asignación de valores e interfaz de lectura, getter - setter ), que imitan el acceso directo al campo. Estos bloques se denominan "propiedades" y son casi idénticos en el nombre específico de su campo (por ejemplo, un nombre de campo puede comenzar con una letra minúscula, pero un nombre de propiedad puede comenzar con una letra mayúscula). Otra manifestación del carácter de interfaz de una clase es que al copiar la variable correspondiente mediante asignación, solo se copia la interfaz, pero no los datos en sí, es decir, la clase es un tipo de datos de referencia . Una variable de objeto de un tipo de clase dado se denomina instancia de esa clase. Al mismo tiempo, en algunos sistemas de ejecución, una clase también puede ser representada por algún objeto durante la ejecución del programa a través de la identificación dinámica del tipo de datos . Por lo general, las clases se diseñan de tal manera que garanticen la integridad de los datos del objeto, así como una interfaz cómoda y sencilla, adecuada a la naturaleza del objeto y la tarea que se está resolviendo. A su vez, la herencia garantiza la integridad del área temática de los objetos y sus interfaces, así como la conveniencia de su diseño. Un objeto Una entidad en el espacio de direcciones de un sistema informático que aparece cuando se crea una instancia de una clase (por ejemplo, después de ejecutar los resultados de la compilación y vincular el código fuente para la ejecución).
Luca Cardelli y Martin Abadi construyeron una justificación teórica para la programación orientada a objetos y una clasificación basada en esta justificación [5] [6] [7] [8] . Señalan que los conceptos y categorías que han identificado no se encuentran juntos en todos los lenguajes OO, la mayoría de los lenguajes admiten solo subconjuntos de la teoría y, a veces, desviaciones peculiares de ella.
Conceptos clave:
Una clase describe un comportamiento abstracto. Los tipos de objetos se crean sobre una clase agregando varios campos y métodos privados. El constructor genera un objeto (es decir, un valor de un tipo de objeto, tradicionalmente llamado "instancia de una clase") en función de los parámetros iniciales.
Los principios básicos de programación orientada a objetos tradicionalmente enumerados no apelan a esta justificación teórica, pero son dogmas que están bien establecidos en la comunidad (lo que conduce a una gran dispersión de opciones de presentación en diferentes fuentes). En su mayor parte pertenecen a los idiomas: los descendientes de Algol y Simula ; en menor medida, a los descendientes de Smalltalk (en particular, el principio mencionado a menudo de ocultarse en los descendientes de Smalltalk es semánticamente inaccesible e ideológicamente considerado insignificante). En mucha mayor medida, los conceptos de programación orientada a objetos con base teórica admiten lenguajes orientados a objetos que se han desarrollado en el campo de la programación funcional : OCaml , dialectos de Haskell (O'Haskell, Mondrian), sucesor ML . Además, las ideas principales del modelado de objetos en este caso no requieren apoyo directo del lenguaje, pero pueden emularse con relativa facilidad [9] .
Las diferencias más notables en la manifestación de indicadores de calidad entre idiomas de diferentes tipos son:
Giuseppe Castagna 11 ] [ 12 ] [ 13 ] .
OOP surgió como resultado del desarrollo de la ideología de la programación procedimental , donde los datos y las subrutinas (procedimientos, funciones) para procesarlos no están formalmente relacionados. Para el desarrollo posterior de la programación orientada a objetos, los conceptos de evento (la llamada programación orientada a eventos ) y componente ( programación de componentes , COP) suelen ser de gran importancia .
Los objetos interactúan a través de mensajes . El resultado del mayor desarrollo de OOP, aparentemente, será la programación orientada a agentes , donde los agentes son partes independientes del código en el nivel de ejecución. Los agentes interactúan modificando el entorno en el que se encuentran.
Las construcciones del lenguaje que no están directamente relacionadas con los objetos por diseño, pero que los acompañan para su funcionamiento seguro ( situaciones excepcionales , comprobaciones) y eficiente, se encapsulan a partir de ellos en aspectos (en la programación orientada a aspectos ). La programación orientada a objetos amplía el concepto de objeto al proporcionar una interacción más unificada e independiente entre objetos. Puede ser una etapa de transición entre OOP y programación de agentes en términos de su interacción independiente.
El primer lenguaje de programación en proponer los conceptos básicos que luego se convirtieron en un paradigma fue Simula , pero el término "orientado a objetos" no se usó en el contexto del uso de este lenguaje. En el momento de su aparición en 1967, en él se proponían ideas revolucionarias: objetos, clases, métodos virtuales , etc., pero todo esto no fue percibido por los contemporáneos como algo grandioso. De hecho, Simula era un "Algol con clases", lo que facilita la expresión de muchos conceptos complejos en la programación de procedimientos . El concepto de una clase en Simula se puede definir completamente a través de la composición de construcciones de Algol (es decir, una clase en Simula es algo complejo, descrito por medio de primitivas).
Alan Kay y Dan Ingalls ofrecieron un "nuevo ángulo" (aparte del procedimental) de la programación en el lenguaje Smalltalk . Aquí, el concepto de clase se ha convertido en la idea fundamental para todas las demás construcciones del lenguaje (es decir, una clase en Smalltalk es una primitiva a través de la cual se describen construcciones más complejas). Fue él quien se convirtió en el primer lenguaje de programación orientado a objetos generalizado .
Actualmente, la cantidad de lenguajes de programación aplicados ( lista de lenguajes ) que implementan el paradigma orientado a objetos es la más grande en relación con otros paradigmas. Los lenguajes más comunes en la industria (C++, Delphi, C#, Java, etc.) implementan el modelo de objetos Simula. Ejemplos de lenguajes basados en el modelo Smoltok son Objective-C, Python, Ruby.
En el centro de OOP está el concepto de un objeto. Un objeto es una entidad a la que se pueden enviar mensajes y que puede responder a ellos utilizando sus datos. Un objeto es una instancia de una clase. Los datos del objeto se ocultan del resto del programa. La encapsulación implica esconderse (¡pero no es así!).
La presencia de encapsulación es suficiente para la objetividad de un lenguaje de programación, pero aún no significa su orientación a objetos; esto requiere la presencia de herencia .
Pero incluso la presencia de encapsulación y herencia no hace que el lenguaje de programación esté totalmente orientado a objetos desde el punto de vista de la programación orientada a objetos. Las principales ventajas de OOP aparecen solo cuando el lenguaje de programación implementa polimorfismo de subtipo : la capacidad de manejar objetos con diferentes implementaciones de manera uniforme, siempre que haya una interfaz común.
OOP tiene más de cuarenta años de historia, pero a pesar de esto, todavía no existe una definición clara y generalmente aceptada de esta tecnología [14] . Los principios básicos establecidos en los primeros sistemas y lenguajes de objetos han sufrido un cambio significativo (o distorsión) y se han agregado con numerosas implementaciones posteriores. Además, desde aproximadamente mediados de la década de 1980, se puso de moda el término "orientado a objetos" , por lo que le sucedió lo mismo que un poco antes con el término "estructural" (que se puso de moda tras la difusión de estructurado ). tecnología de programación ): se convirtió en un "adjunto" artificial a los nuevos desarrollos para hacerlos atractivos. Björn Stroustrup escribió en 1988 que la justificación de la "orientación a objetos" de algo, en la mayoría de los casos, se reduce a un silogismo incorrecto : "X es bueno. La orientación a objetos es buena. Por lo tanto , X está orientado a objetos".
Timothy Budd escribe [15] [16] :
Roger King argumentó que su gato estaba orientado a objetos. Además de sus otras virtudes, el gato demuestra un comportamiento característico, responde a los mensajes, está dotado de reacciones heredadas y controla su propio estado interno, completamente independiente.
Según Alan Kay , el creador del lenguaje Smalltalk , considerado uno de los "padres fundadores" de la programación orientada a objetos, el enfoque orientado a objetos consiste en el siguiente conjunto de principios básicos (citados del libro antes mencionado de T. Budd).
Así, un programa es un conjunto de objetos que tienen estado y comportamiento. Los objetos se comunican a través de mensajes. Se construye naturalmente una jerarquía de objetos: el programa en su conjunto es un objeto, para realizar sus funciones se refiere a los objetos incluidos en él, que a su vez realizan lo solicitado refiriéndose a otros objetos del programa. Naturalmente, para evitar la recurrencia interminable en las llamadas, en algún momento el objeto transforma el mensaje que se le dirige en mensajes para objetos estándar del sistema proporcionados por el lenguaje y el entorno de programación.
La estabilidad y la controlabilidad del sistema están garantizadas por una clara división de responsabilidad de los objetos (un objeto determinado es responsable de cada acción), una definición inequívoca de interfaces para la interacción entre objetos y un aislamiento completo de la estructura interna de un objeto de el ambiente externo (encapsulación).
OOP se puede definir de muchas otras maneras.
La aparición en OOP de un concepto separado de una clase se deriva naturalmente del deseo de tener muchos objetos con un comportamiento similar. Una clase en OOP es un tipo de datos abstracto puro creado por un programador. Desde este punto de vista, los objetos son valores de un tipo abstracto dado, y una definición de clase especifica la estructura interna de los valores y el conjunto de operaciones que se pueden realizar sobre estos valores. La conveniencia de una jerarquía de clases (y, por lo tanto, de herencia) se deriva de los requisitos para la reutilización de código: si varias clases tienen un comportamiento similar, no tiene sentido duplicar su descripción, es mejor separar la parte común en una clase principal común y dejar sólo elementos diferentes en la descripción de estas clases mismas.
La necesidad de compartir objetos de diferentes clases que puedan procesar el mismo tipo de mensajes requiere compatibilidad con el polimorfismo : la capacidad de escribir diferentes objetos en variables del mismo tipo. En tales condiciones, un objeto que envía un mensaje puede no saber exactamente a qué clase pertenece el destinatario, y los mismos mensajes enviados a variables del mismo tipo que contienen objetos de diferentes clases provocarán una reacción diferente.
El concepto de intercambio de mensajes requiere una explicación aparte . Inicialmente (por ejemplo, en el mismo Smalltalk ), la interacción de objetos se presentaba como un intercambio de mensajes "real", es decir, la transferencia de un objeto a otro de un objeto de mensaje especial. Este modelo es extremadamente general. Es perfecto, por ejemplo, para describir computación paralela utilizando objetos activos , cada uno de los cuales tiene su propio hilo de ejecución y trabaja simultáneamente con los demás. Dichos objetos pueden comportarse como unidades informáticas separadas y completamente autónomas. El envío de mensajes resuelve naturalmente el problema del procesamiento de mensajes por objetos asignados a variables polimórficas: independientemente de cómo se declare la variable, el mensaje procesa el código de la clase a la que pertenece el objeto asignado a la variable. Este enfoque se implementa en los lenguajes de programación Smalltalk , Ruby , Objective-C , Python .
Sin embargo, la generalidad del mecanismo de mensajería tiene otro lado: el paso de mensajes "completo" requiere una sobrecarga adicional, lo que no siempre es aceptable. Por lo tanto, en muchos lenguajes de programación orientados a objetos modernos, se usa el concepto de "enviar un mensaje como una llamada a un método" : los objetos tienen métodos accesibles desde el exterior, cuyas llamadas aseguran la interacción de los objetos. Este enfoque se ha implementado en una gran cantidad de lenguajes de programación, incluidos C ++ , Object Pascal , Java , Oberon-2 . Sin embargo, esto lleva al hecho de que los mensajes ya no son objetos independientes y, como resultado, no tienen atributos, lo que reduce las posibilidades de programación. Algunos lenguajes usan una representación híbrida, demostrando los beneficios de ambos enfoques al mismo tiempo, por ejemplo, CLOS , Python .
El concepto de métodos virtuales , apoyado por estos y otros lenguajes modernos, apareció como un medio para asegurar que los métodos deseados se ejecutan cuando se utilizan variables polimórficas, es decir, en esencia, como un intento de ampliar la capacidad de llamar a métodos para implementar parte de la funcionalidad proporcionada por el mecanismo de procesamiento de mensajes.
Como se mencionó anteriormente, en los lenguajes de programación modernos orientados a objetos, cada objeto es un valor que pertenece a una determinada clase . Una clase es un tipo de datos compuesto declarado por un programador que contiene :
Campos de información Parámetros del objeto (por supuesto, no todos, pero solo los necesarios en el programa) que definen su estado (propiedades del objeto del área temática). A veces, los campos de datos de un objeto se denominan propiedades del objeto, lo que puede resultar confuso. De hecho, los campos son valores (variables, constantes) declarados como pertenecientes a la clase. Métodos Procedimientos y funciones asociadas a la clase. Definen las acciones que se pueden realizar en un objeto de ese tipo y que el propio objeto puede realizar.Las clases pueden heredar unas de otras. La clase secundaria recibe todos los campos y métodos de la clase principal, pero puede complementarlos con los suyos propios o anular los existentes. La mayoría de los lenguajes de programación solo admiten la herencia única (una clase puede tener solo una clase principal), solo unos pocos permiten la herencia múltiple: la generación de una clase a partir de dos o más clases principales. La herencia múltiple crea una serie de problemas, tanto lógicos como puramente de implementación, por lo que su soporte completo no está muy extendido. En cambio, en la década de 1990, apareció el concepto de interfaz y comenzó a introducirse activamente en los lenguajes orientados a objetos . Una interfaz es una clase sin campos ni implementación, que incluye solo encabezados de métodos. Si una clase hereda (o se dice que implementa) una interfaz, debe implementar todos sus métodos miembros. El uso de interfaces proporciona una alternativa relativamente económica a la herencia múltiple.
La interacción de los objetos en la gran mayoría de los casos se proporciona llamando a los métodos de los demás.
La encapsulación se proporciona por los siguientes medios:
Control de acceso Dado que los métodos de clase pueden ser puramente internos, proporcionando la lógica del funcionamiento del objeto, y externos, con la ayuda de los cuales interactúan los objetos, es necesario asegurarse de que los primeros estén ocultos mientras que los segundos sean accesibles desde el exterior. Para ello, se introducen construcciones sintácticas especiales en los lenguajes que establecen explícitamente el alcance de cada miembro de la clase. Tradicionalmente, estos son modificadores públicos, protegidos y privados, que denotan, respectivamente, miembros públicos de la clase, miembros de la clase accesibles dentro de la clase y desde clases descendientes, y ocultos, accesibles solo dentro de la clase. La nomenclatura específica de los modificadores y su significado preciso varía según el idioma. Métodos de acceso Los campos de clase en general no deberían ser accesibles desde el exterior, ya que dicho acceso permitiría cambiar arbitrariamente el estado interno de los objetos. Por lo tanto, los campos suelen declararse ocultos (o el lenguaje en principio no permite acceder a los campos de la clase desde fuera), y se utilizan métodos especiales llamados accesores para acceder a los datos de los campos. Dichos métodos devuelven el valor de un campo en particular o escriben un nuevo valor en este campo. Al escribir, el accesor puede comprobar que el valor que se está escribiendo es válido y, si es necesario, realizar otras manipulaciones en los datos del objeto para que siga siendo correcto (consistencia interna). Los métodos de acceso también se denominan accesores (del inglés access - access) y, por separado, getters ( inglés get - get) y setters ( inglés set - set) [17] . Propiedades del objeto Pseudocampos disponibles para lectura y/o escritura. Las propiedades parecen campos y se usan de la misma manera que los campos accesibles (con algunas excepciones), pero de hecho, cuando se accede a ellos, se llaman a los métodos de acceso. Por lo tanto, las propiedades pueden considerarse como campos de datos "inteligentes" que acompañan el acceso a los datos internos del objeto con algunas acciones adicionales (por ejemplo, cuando el cambio de la coordenada del objeto va acompañado de su redibujado en un nuevo lugar). Las propiedades, de hecho, no son más que azúcar sintáctica , ya que no agregan ninguna característica nueva, sino que solo ocultan la llamada a los métodos de acceso. La implementación del lenguaje específico de las propiedades puede variar. Por ejemplo, en C# , una declaración de propiedad contiene directamente un código de acceso al que solo se llama cuando se trabaja con propiedades, es decir, no requiere métodos de acceso independientes que estén disponibles para una llamada inmediata. En Delphi, una declaración de propiedad contiene solo los nombres de los métodos de acceso que deben llamarse cuando se accede al campo. Los propios accesores son métodos ordinarios con algunos requisitos de firma adicionales .El polimorfismo se implementa introduciendo reglas en el lenguaje, según las cuales a una variable del tipo "clase" se le puede asignar un objeto de cualquier clase descendiente de su clase.
OOP se centra en el desarrollo de grandes sistemas de software desarrollados por un equipo de programadores (quizás bastante grande). El diseño del sistema como un todo, la creación de componentes individuales y su integración en el producto final, a menudo lo realizan diferentes personas, y no hay un solo especialista que sepa todo sobre el proyecto.
El diseño orientado a objetos se centra en la descripción de la estructura del sistema que se está diseñando (prioridad a la descripción de su comportamiento, en contraste con la programación funcional ), es decir, en realidad, en respuesta a dos preguntas principales:
La asignación de partes se lleva a cabo de tal manera que cada una tenga un conjunto mínimo y definido con precisión de funciones (deberes) realizadas, y al mismo tiempo interactúe con otras partes lo menos posible.
Un mayor refinamiento conduce a la selección de fragmentos más pequeños de la descripción. A medida que se detalla la descripción y se determina la responsabilidad, se revelan los datos que es necesario almacenar, la presencia de agentes similares en el comportamiento, que se convierten en candidatos para la implementación en forma de clases con ancestros comunes. Después de la selección de componentes y la definición de interfaces entre ellos, la implementación de cada componente puede llevarse a cabo casi independientemente de los demás (por supuesto, sujeto a la disciplina tecnológica apropiada).
De gran importancia es la construcción correcta de la jerarquía de clases. Uno de los problemas más conocidos de los grandes sistemas construidos con tecnología OOP es el llamado problema de fragilidad de la clase base . Consiste en el hecho de que en las últimas etapas de desarrollo, cuando se ha construido la jerarquía de clases y se ha desarrollado una gran cantidad de código sobre su base, resulta difícil o incluso imposible realizar cambios en el código de las clases base de la jerarquía (a partir de las cuales se generan todas o muchas de las clases que operan en el sistema). Incluso si los cambios que realiza no afectan la interfaz de la clase base, cambiar su comportamiento puede afectar a las clases descendientes de forma impredecible. En el caso de un sistema grande, el desarrollador de la clase base simplemente no puede predecir las consecuencias de los cambios, ni siquiera sabe cómo se usa exactamente la clase base y en qué características de su comportamiento funciona correctamente las clases descendientes. depende
La programación de componentes es la siguiente etapa en el desarrollo de OOP; La programación orientada a prototipos y clases son enfoques diferentes para crear un programa que se puede combinar, con sus propias ventajas y desventajas.
La programación orientada a componentes es una especie de "complemento" sobre OOP, un conjunto de reglas y restricciones destinadas a construir grandes sistemas de software en desarrollo con una larga vida útil. El sistema de software en esta metodología es un conjunto de componentes con interfaces bien definidas. Los cambios en un sistema existente se realizan mediante la creación de nuevos componentes además o como reemplazo de los existentes anteriormente. Al crear nuevos componentes basados en los creados anteriormente, se prohíbe el uso de la herencia de implementación: un nuevo componente solo puede heredar las interfaces del base. De esta forma, la programación de componentes evita el problema de la fragilidad de la clase base.
La programación de prototipos , aunque conservaba algunas de las características de OOP, abandonó los conceptos básicos de clase y herencia.
La programación orientada a la clase es una programación centrada en los datos, donde los datos y el comportamiento están inextricablemente vinculados. Juntos, los datos y el comportamiento constituyen una clase. En consecuencia, en los lenguajes basados en el concepto de "clase", todos los objetos se dividen en dos tipos principales: clases e instancias. Una clase define una estructura y funcionalidad (comportamiento) que es la misma para todas las instancias de esa clase. Una instancia es un soporte de datos, es decir, tiene un estado que cambia de acuerdo con el comportamiento especificado por la clase. En los lenguajes orientados a clases, se crea una nueva instancia llamando al constructor de clases (quizás con un conjunto de parámetros). La instancia resultante tiene la estructura y el comportamiento codificados por su clase.
Grady Booch señala [18] las siguientes razones de la disminución del rendimiento del programa debido al uso de herramientas orientadas a objetos:
Enlace de método dinámico Garantizar el comportamiento polimórfico de los objetos lleva a la necesidad de vincular los métodos llamados por el programa (es decir, determinar qué método en particular se llamará) no en la etapa de compilación, sino durante la ejecución del programa, lo que lleva tiempo adicional. Al mismo tiempo, el enlace dinámico en realidad se requiere para no más del 20 % de las llamadas, pero algunos lenguajes OOP lo usan todo el tiempo. Profundidad significativa de abstracción El desarrollo de programación orientada a objetos a menudo conduce a la creación de aplicaciones "en capas", donde la ejecución de la acción deseada por parte de un objeto se reduce a muchas llamadas a objetos de un nivel inferior. En una aplicación de este tipo, hay muchas llamadas a métodos y devoluciones de métodos, lo que, por supuesto, afecta el rendimiento. Código de desenfoque de herencia El código relacionado con las clases "finales" de la jerarquía de herencia, que normalmente usa el programa directamente, se encuentra no solo en estas clases, sino también en sus clases antepasadas. Los métodos que pertenecen a la misma clase en realidad se describen en diferentes clases. Esto lleva a dos cosas molestas:A pesar de estas deficiencias, Booch argumenta que los beneficios de usar OOP son mayores. Además, las ganancias de rendimiento de una mejor organización del código OOP, dice, en algunos casos compensa la sobrecarga adicional de ejecutar el programa. También puede notar que muchos efectos de degradación del rendimiento pueden suavizarse o incluso eliminarse por completo debido a la optimización del código de alta calidad por parte del compilador. Por ejemplo, la disminución antes mencionada en la velocidad de acceso a los campos de clase debido al uso de accesores se elimina si el compilador usa la sustitución en línea en lugar de llamar al accesor (los compiladores modernos hacen esto con bastante confianza).
A pesar de algunas críticas al OOP, este paradigma se utiliza actualmente en la gran mayoría de los proyectos industriales. Sin embargo, no se puede asumir que OOP es la mejor técnica de programación en todos los casos.
Críticas a la OLP:
Si tratamos de clasificar las críticas a la programación orientada a objetos, podemos destacar varios aspectos de las críticas a este enfoque de la programación.
Críticas a la publicidad orientada a objetos Se critica lo explícito o implícito en los escritos de algunos propagandistas de programación orientada a objetos, así como en materiales promocionales para herramientas de desarrollo "orientadas a objetos", la noción de programación de objetos como una especie de enfoque omnipotente que elimina mágicamente la complejidad de la programación. Como señalaron muchas personas, incluidos Brooks y Dijkstra mencionados anteriormente, "no existe una bala de plata", independientemente del paradigma de programación al que se adhiera un desarrollador, la creación de un sistema de software complejo no trivial siempre implica una inversión significativa de tiempo y recursos intelectuales. De los especialistas más calificados en el campo de la programación orientada a objetos, nadie, por regla general, niega la validez de este tipo de crítica. Desafiando la eficiencia del desarrollo de programación orientada a objetos Los críticos cuestionan la tesis de que desarrollar programas orientados a objetos requiere menos recursos o da como resultado un mejor software. Se realiza una comparación de costos de desarrollo por diferentes métodos, en base a lo cual se concluye que el OOP no tiene ventajas en este sentido. Dada la extrema complejidad de la comparación objetiva de varios desarrollos, tales comparaciones son, como mínimo, discutibles. Por otro lado, resulta que las declaraciones sobre la eficacia de la programación orientada a objetos son igualmente controvertidas. Rendimiento de programas orientados a objetos Se señala que una serie de "características innatas" de las tecnologías OOP hacen que los programas construidos sobre su base sean técnicamente menos eficientes en comparación con programas similares que no son objetos. Si bien no se niega que, de hecho, existe una sobrecarga adicional para ejecutar programas OOP (consulte la sección Rendimiento anterior), sin embargo, los críticos a menudo exageran el impacto en el rendimiento. En las condiciones modernas, cuando las capacidades técnicas de las computadoras son extremadamente grandes y están en constante crecimiento, para la mayoría de los programas de aplicación, la eficiencia técnica es menos significativa que la funcionalidad, la velocidad de desarrollo y la capacidad de mantenimiento. Solo para una clase muy limitada de programas (software de sistemas integrados, controladores de dispositivos, software de sistemas de bajo nivel, software científico), el rendimiento sigue siendo un factor crítico. Críticas a soluciones tecnológicas individuales en lenguajes y librerías OOP Esta crítica es numerosa, pero no afecta a la POO como tal, sino a la aceptabilidad y aplicabilidad en casos concretos de determinadas implementaciones de sus mecanismos. Uno de los objetos favoritos de las críticas es el lenguaje C ++, que es uno de los lenguajes OOP industriales más comunes.Muchos lenguajes modernos están diseñados específicamente para facilitar la programación orientada a objetos. Sin embargo, puede aplicar técnicas de OOP a un lenguaje no orientado a objetos y viceversa, el uso de un lenguaje orientado a objetos no significa que el código se convierta automáticamente en orientado a objetos.
Normalmente, un lenguaje orientado a objetos (OOL) contiene el siguiente conjunto de elementos:
Algunos idiomas agregan ciertas características adicionales al conjunto mínimo especificado. Entre ellos:
Algunos lenguajes siguen los principios de OOP al completo; en ellos, todos los elementos principales son objetos que tienen un estado y métodos asociados. Ejemplos de tales lenguajes son Smalltalk , Eiffel . Existen lenguajes híbridos que combinan el subsistema de objetos en su totalidad con subsistemas de otros paradigmas como “dos o más lenguajes en uno”, que permiten combinar modelos de objetos con otros en un mismo programa, y desdibujar la línea entre orientado a objetos y otros paradigmas debido a características no estándar que se equilibran entre OOP y otros paradigmas (como envío múltiple , clases paramétricas, la capacidad de manipular métodos de clase como objetos independientes, etc.). Ejemplos de tales lenguajes son CLOS , Dylan , OCaml , Python , Ruby , Objective-C . Sin embargo, los lenguajes más comunes incluyen la emulación de modelos de objetos además de la semántica imperativa más tradicional. Alan Kay llamó a tales lenguajes " aglutinación de características " en oposición a la " cristalización del estilo " de los lenguajes que encarnan directamente un determinado paradigma [26] . Ejemplos de tales lenguajes son Simula , C++ , Visual Basic , Delphi , Modula , Modula-2 , Java , C# , PHP .
diccionarios y enciclopedias | ||||
---|---|---|---|---|
|
Desarrollo de software | |
---|---|
Proceso | |
Conceptos de alto nivel | |
Direcciones |
|
Metodologías de desarrollo | |
Modelos |
|
Figuras notables |
|