Abstracción (ciencias de la computación)

Compartir Imprimir Citar
Técnica para organizar la complejidad de los sistemas informáticos

La esencia de la abstracción es preservar la información relevante en un contexto dado, y olvidar la información que es irrelevante en ese contexto.

- John V. Guttag

En ingeniería de software e informática, abstracción es:

La abstracción, en general, es un concepto fundamental en informática y desarrollo de software. El proceso de abstracción también puede denominarse modelado y está estrechamente relacionado con los conceptos de teoría y diseño. Los modelos también pueden considerarse tipos de abstracciones por su generalización de aspectos de la realidad.

La abstracción en informática está estrechamente relacionada con la abstracción en matemáticas debido a su enfoque común en construir abstracciones como objetos, pero también está relacionada con otras nociones de abstracción utilizadas en otros campos como el arte.

Las abstracciones también pueden referirse a objetos y sistemas del mundo real, reglas de sistemas computacionales o reglas de lenguajes de programación que llevan o utilizan características de la abstracción en sí, como:

Fundamento

La informática opera mayormente independientemente del mundo concreto. El hardware implementa un modelo de computación que es intercambiable con otros. El software está estructurado en arquitecturas para permitir que los humanos creen los enormes sistemas concentrándose en unos pocos problemas a la vez. Estas arquitecturas están hechas de elecciones específicas de abstracciones. La Décima Regla de Greenspun es un aforismo sobre cómo tal arquitectura es a la vez inevitable y compleja.

Una forma central de abstracción en la informática es la abstracción del lenguaje: se desarrollan nuevos lenguajes artificiales para expresar aspectos específicos de un sistema. Los lenguajes de modelado ayudan en la planificación. Los lenguajes informáticos se pueden procesar con una computadora. Un ejemplo de este proceso de abstracción es el desarrollo generacional de los lenguajes de programación desde el lenguaje máquina hasta el lenguaje ensamblador y el lenguaje de alto nivel. Cada etapa se puede utilizar como un trampolín para la siguiente etapa. La abstracción del lenguaje continúa, por ejemplo, en lenguajes de secuencias de comandos y lenguajes de programación específicos de dominio.

Dentro de un lenguaje de programación, algunas funciones permiten al programador crear nuevas abstracciones. Estos incluyen subrutinas, módulos, polimorfismos y componentes de software. Algunas otras abstracciones, como los patrones de diseño de software y los estilos arquitectónicos, permanecen invisibles para un traductor y solo operan en el diseño de un sistema.

Algunas abstracciones intentan limitar el rango de conceptos que un programador debe conocer, al ocultar por completo las abstracciones en las que se basan. El ingeniero de software y escritor Joel Spolsky ha criticado estos esfuerzos al afirmar que todas las abstracciones tienen fugas, que nunca pueden ocultar por completo los detalles a continuación; sin embargo, esto no niega la utilidad de la abstracción.

Algunas abstracciones están diseñadas para interactuar con otras abstracciones; por ejemplo, un lenguaje de programación puede contener una interfaz de función externa para realizar llamadas al lenguaje de nivel inferior.

Funciones de abstracción

Lenguajes de programación

Diferentes lenguajes de programación proporcionan diferentes tipos de abstracción, según las aplicaciones previstas para el lenguaje. Por ejemplo:

Métodos de especificación

Los analistas han desarrollado varios métodos para especificar formalmente los sistemas de software. Algunos métodos conocidos incluyen:

Idiomas de especificación

Los lenguajes de especificación generalmente se basan en abstracciones de un tipo u otro, ya que las especificaciones generalmente se definen antes en un proyecto (y en un nivel más abstracto) que una implementación final. El lenguaje de especificación UML, por ejemplo, permite la definición de clases abstractas, que en un proyecto en cascada permanecen abstractas durante la fase de arquitectura y especificación del proyecto.

Abstracción de controles

Los lenguajes de programación ofrecen abstracción de control como uno de los propósitos principales de su uso. Las máquinas informáticas entienden operaciones en un nivel muy bajo, como mover algunos bits de una ubicación de la memoria a otra ubicación y producir la suma de dos secuencias de bits. Los lenguajes de programación permiten que esto se haga en el nivel superior. Por ejemplo, considere esta declaración escrita en forma de Pascal:

a:= (1 + 2) * 5

Para un ser humano, esto parece un cálculo bastante simple y obvio ("uno más dos es tres, por cinco es quince"). Sin embargo, los pasos de bajo nivel necesarios para llevar a cabo esta evaluación y devolver el valor '15', y luego asignar ese valor a la variable 'a', son en realidad bastante sutiles y complejos.. Los valores deben convertirse a representación binaria (a menudo, una tarea mucho más complicada de lo que uno pensaría) y los cálculos descompuestos (por el compilador o el intérprete) en instrucciones de ensamblaje (nuevamente, que son mucho menos intuitivas para el programador: operaciones como cambiar un registro binario a la izquierda, o agregar el complemento binario de los contenidos de un registro a otro, simplemente no es como los humanos piensan sobre las operaciones aritméticas abstractas de suma o multiplicación). Finalmente, asignando el valor resultante de "15" a la variable etiquetada como "a", de modo que "a" se puede usar más tarde, implica información adicional 'detrás de escena' pasos para buscar la etiqueta de una variable y la ubicación resultante en la memoria física o virtual, almacenar la representación binaria de "15" a esa ubicación de memoria, etc.

Sin abstracción de control, un programador necesitaría especificar todos los pasos de registro/nivel binario cada vez que simplemente quisiera sumar o multiplicar un par de números y asignar el resultado a una variable. Tal duplicación de esfuerzos tiene dos graves consecuencias negativas:

  1. obliga al programador a repetir constantemente tareas bastante comunes cada vez que se necesita una operación similar
  2. obliga al programador a programar para el conjunto de hardware e instrucción particular

Programación estructurada

La programación estructurada implica la división de tareas complejas del programa en partes más pequeñas con un control de flujo claro e interfaces entre los componentes, con una reducción de la complejidad potencial de los efectos secundarios.

En un programa simple, esto puede tener como objetivo garantizar que los bucles tengan puntos de salida únicos u obvios y (donde sea posible) tener puntos de salida únicos de funciones y procedimientos.

En un sistema más grande, puede implicar dividir tareas complejas en muchos módulos diferentes. Considere un sistema que maneje la nómina en los barcos y en las oficinas en tierra:

Estas capas producen el efecto de aislar los detalles de implementación de un componente y sus diversos métodos internos de los demás. La programación orientada a objetos adopta y amplía este concepto.

Abstracción de datos

La abstracción de datos impone una separación clara entre las propiedades abstractas de un tipo de datos y los detalles concretos de su implementación. Las propiedades abstractas son aquellas que son visibles para el código del cliente que utiliza el tipo de datos (la interfaz con el tipo de datos), mientras que la implementación concreta se mantiene completamente privada y, de hecho, puede cambiar, por ejemplo, para incorporar mejoras de eficiencia a lo largo del tiempo. La idea es que dichos cambios no deberían tener ningún impacto en el código del cliente, ya que no implican ninguna diferencia en el comportamiento abstracto.

Por ejemplo, se podría definir un tipo de datos abstracto llamado tabla de búsqueda que asocia de forma única claves con valores, y en la que los valores pueden ser recupera especificando sus claves correspondientes. Dicha tabla de búsqueda se puede implementar de varias maneras: como una tabla hash, un árbol de búsqueda binaria o incluso una lista lineal simple de pares (clave:valor). En lo que respecta al código de cliente, las propiedades abstractas del tipo son las mismas en todos los casos.

Por supuesto, todo esto depende de obtener los detalles correctos de la interfaz en primer lugar, ya que cualquier cambio allí puede tener un gran impacto en el código del cliente. Como una forma de ver esto: la interfaz forma un contrato sobre el comportamiento acordado entre el tipo de datos y el código del cliente; cualquier cosa no detallada en el contrato está sujeta a cambios sin previo aviso.

Extracción manual de datos

Si bien gran parte de la abstracción de datos se produce a través de la informática y la automatización, hay momentos en que este proceso se realiza de forma manual y sin intervención de programación. Una forma de entender esto es a través de la abstracción de datos dentro del proceso de realizar una revisión sistemática de la literatura. En esta metodología, uno o varios extractores extraen los datos cuando se realiza un metanálisis, y los errores se reducen mediante la extracción dual de datos seguida de una verificación independiente, conocida como adjudicación.

Abstracción en programación orientada a objetos

En la teoría de la programación orientada a objetos, la abstracción implica la facilidad de definir objetos que representan "actores" que pueden realizar trabajos, informar y cambiar su estado, y "comunicarse" con otros objetos del sistema. El término encapsulación se refiere a ocultar los detalles del estado, pero extiende el concepto de tipo de datos de lenguajes de programación anteriores para asociar comportamiento más fuertemente con los datos, y estandariza la forma en que interactúan diferentes tipos de datos, es el comienzo de la abstracción. Cuando la abstracción procede a las operaciones definidas, permitiendo sustituir objetos de diferentes tipos, se denomina polimorfismo. Cuando se procede en sentido contrario, dentro de los tipos o clases, estructurándolos para simplificar un conjunto complejo de relaciones, se denomina delegación o herencia.

Varios lenguajes de programación orientados a objetos ofrecen facilidades similares para la abstracción, todo para respaldar una estrategia general de polimorfismo en la programación orientada a objetos, que incluye la sustitución de un tipo por otro en el mismo rol o uno similar. Aunque generalmente no se admite, una configuración, imagen o paquete puede predeterminar muchos de estos enlaces en tiempo de compilación, tiempo de enlace o tiempo de carga. Esto dejaría solo un mínimo de dichos enlaces para cambiar en tiempo de ejecución.

Common Lisp Object System o Self, por ejemplo, presenta menos distinción de instancia de clase y más uso de delegación para polimorfismo. Los objetos y funciones individuales se abstraen de manera más flexible para encajar mejor con una herencia funcional compartida de Lisp.

C++ ejemplifica otro extremo: se basa en gran medida en las plantillas y la sobrecarga y otros enlaces estáticos en tiempo de compilación, lo que a su vez tiene ciertos problemas de flexibilidad.

Aunque estos ejemplos ofrecen estrategias alternativas para lograr la misma abstracción, no alteran fundamentalmente la necesidad de admitir sustantivos abstractos en el código: toda la programación se basa en la capacidad de abstraer verbos como funciones, sustantivos como estructuras de datos y como procesos.

Considere, por ejemplo, un fragmento de Java de muestra para representar algunos "animales" de granja comunes; a un nivel de abstracción adecuado para modelar aspectos simples de su hambre y alimentación. Define una clase Animal para representar tanto el estado del animal como sus funciones:

público clase Animal extensiones Vivir{} privado Ubicación Loc; privado doble energyReserves; público boolean isHungry() {} retorno energyReserves . 2.5; } público vacío comer()Alimentos alimentos) {} // Comida de consumo energyReserves += alimentos.getCalories(); } público vacío Mover()Ubicación ubicación) {} // Mover a la nueva ubicación esto.Loc = ubicación; }}

Con la definición anterior, uno podría crear objetos de tipo Animal y llamar a sus métodos como esto:

elPig = nuevo Animal();elCow = nuevo Animal();si ()elPig.isHungry()) {} elPig.comer()TableScraps);}si ()elCow.isHungry()) {} elCow.comer()hierba);}elCow.Mover()el Barn);

En el ejemplo anterior, la clase Animal es una abstracción utilizada en lugar de un animal real, LivingThing es una abstracción adicional (en este caso una generalización) de Animal.

Si se necesita una jerarquía de animales más diferenciada (para diferenciar, por ejemplo, los que proporcionan leche de los que solo proporcionan carne al final de sus vidas), ese es un nivel intermedio de abstracción, probablemente DairyAnimal (vacas, cabras) que comerían alimentos adecuados para dar buena leche, y MeatAnimal (cerdos, novillos) que comerían alimentos para dar la mejor calidad de carne.

Tal abstracción podría eliminar la necesidad de que el codificador de la aplicación especifique el tipo de alimento, por lo que podrían concentrarse en el horario de alimentación. Las dos clases podrían relacionarse mediante herencia o de forma independiente, y el programador podría definir diversos grados de polimorfismo entre los dos tipos. Estas facilidades tienden a variar drásticamente entre idiomas, pero en general cada uno puede lograr todo lo que es posible con cualquiera de los otros. Muchas sobrecargas de operaciones, tipo de datos por tipo de datos, pueden tener el mismo efecto en tiempo de compilación que cualquier grado de herencia u otros medios para lograr el polimorfismo. La notación de clase es simplemente la conveniencia de un codificador.

Diseño orientado a objetos

Las decisiones sobre qué abstraer y qué mantener bajo el control del codificador se convierten en la principal preocupación del diseño orientado a objetos y el análisis de dominio; en realidad, determinar las relaciones relevantes en el mundo real es la preocupación del análisis orientado a objetos o legado. análisis.

En general, para determinar la abstracción adecuada, se deben tomar muchas decisiones pequeñas sobre el alcance (análisis de dominio), determinar con qué otros sistemas se debe cooperar (análisis heredado) y luego realizar un análisis detallado orientado a objetos que se expresa dentro del proyecto. restricciones de tiempo y presupuesto como un diseño orientado a objetos. En nuestro ejemplo simple, el dominio es el corral, los cerdos y vacas vivos y sus hábitos alimenticios son las restricciones heredadas, el análisis detallado es que los codificadores deben tener la flexibilidad para alimentar a los animales con lo que está disponible y, por lo tanto, no hay motivo para codificar. el tipo de comida en la clase en sí, y el diseño es una sola clase Animal simple de la cual los cerdos y las vacas son instancias con las mismas funciones. La decisión de diferenciar a DairyAnimal cambiaría el análisis detallado, pero el análisis de dominio y legado no cambiaría; por lo tanto, está completamente bajo el control del programador y se denomina abstracción en la programación orientada a objetos, a diferencia de la abstracción en dominio o legado. análisis.

Consideraciones

Cuando se habla de semántica formal de lenguajes de programación, métodos formales o interpretación abstracta, abstracción se refiere al acto de considerar una definición menos detallada, pero segura, de los comportamientos del programa observados. Por ejemplo, uno puede observar solo el resultado final de las ejecuciones del programa en lugar de considerar todos los pasos intermedios de las ejecuciones. La abstracción se define a un modelo concreto (más preciso) de ejecución.

La abstracción puede ser exacta o fiel con respecto a una propiedad si se puede responder igualmente bien a una pregunta sobre la propiedad en el modelo concreto o abstracto. Por ejemplo, si uno desea saber cuál es el valor del resultado de la evaluación de una expresión matemática que involucra solo números enteros +, -, ×, módulo n, entonces solo necesita realizar todas las operaciones módulo n (una forma familiar de esta abstracción es sacar nueves).

Las abstracciones, sin embargo, aunque no necesariamente exactas, deben ser sonoras. Es decir, debería ser posible obtener respuestas sólidas a partir de ellos, aunque la abstracción pueda simplemente producir un resultado de indecidibilidad. Por ejemplo, los estudiantes de una clase pueden ser abstraídos por sus edades mínimas y máximas; si uno pregunta si cierta persona pertenece a esa clase, simplemente puede comparar la edad de esa persona con las edades mínima y máxima; si su edad está fuera del rango, se puede responder con seguridad que la persona no pertenece a la clase; si no es así, solo se puede responder "no sé".

El nivel de abstracción incluido en un lenguaje de programación puede influir en su usabilidad general. El marco de las dimensiones cognitivas incluye el concepto de gradiente de abstracción en un formalismo. Este marco permite al diseñador de un lenguaje de programación estudiar las compensaciones entre la abstracción y otras características del diseño, y cómo los cambios en la abstracción influyen en la usabilidad del lenguaje.

Las abstracciones pueden resultar útiles cuando se trata de programas informáticos, porque las propiedades no triviales de los programas informáticos son esencialmente indecidibles (consulte el teorema de Rice). Como consecuencia, los métodos automáticos para derivar información sobre el comportamiento de los programas de computadora deben eliminar la terminación (en algunas ocasiones, pueden fallar, bloquearse o nunca dar un resultado), solidez (pueden proporcionar información falsa) o precisión (pueden responder 'No sé' a algunas preguntas).

La abstracción es el concepto central de la interpretación abstracta. La verificación de modelos generalmente se lleva a cabo en versiones abstractas de los sistemas estudiados.

Niveles de abstracción

La informática suele presentar niveles (o, con menor frecuencia, capas) de abstracción, en los que cada nivel representa un modelo diferente de la misma información y procesos, pero con diferentes cantidades de detalle. Cada nivel utiliza un sistema de expresión que involucra un conjunto único de objetos y composiciones que se aplican solo a un dominio particular. Cada uno relativamente abstracto, "superior" se basa en un nivel relativamente concreto, "inferior" nivel, que tiende a proporcionar un nivel cada vez más "granular" representación. Por ejemplo, las puertas se basan en circuitos electrónicos, binario en puertas, lenguaje de máquina en binario, lenguaje de programación en lenguaje de máquina, aplicaciones y sistemas operativos en lenguajes de programación. Cada nivel está incorporado, pero no determinado, por el nivel debajo de él, lo que lo convierte en un lenguaje de descripción que es algo autónomo.

Sistemas de bases de datos

Dado que muchos usuarios de sistemas de bases de datos carecen de una familiaridad profunda con las estructuras de datos de la computadora, los desarrolladores de bases de datos a menudo ocultan la complejidad a través de los siguientes niveles:

Niveles de abstracción de datos de un sistema de bases de datos

Nivel físico: El nivel más bajo de abstracción describe cómo un sistema realmente almacena datos. El nivel físico describe estructuras de datos complejas de bajo nivel en detalle.

Nivel lógico: El siguiente nivel superior de abstracción describe qué datos almacena la base de datos y qué relaciones existen entre esos datos. El nivel lógico describe así una base de datos completa en términos de un pequeño número de estructuras relativamente simples. Aunque la implementación de estructuras simples en el nivel lógico puede involucrar estructuras complejas en el nivel físico, el usuario del nivel lógico no necesita ser consciente de esta complejidad. Esto se conoce como independencia de datos físicos. Los administradores de bases de datos, que deben decidir qué información conservar en una base de datos, utilizan el nivel lógico de abstracción.

Nivel de vista: El nivel más alto de abstracción describe solo una parte de la base de datos completa. Aunque el nivel lógico usa estructuras más simples, la complejidad permanece debido a la variedad de información almacenada en una gran base de datos. Muchos usuarios de un sistema de base de datos no necesitan toda esta información; en cambio, necesitan acceder solo a una parte de la base de datos. El nivel de vista de abstracción existe para simplificar su interacción con el sistema. El sistema puede proporcionar muchas vistas para la misma base de datos.

Arquitectura en capas

La capacidad de proporcionar un diseño de diferentes niveles de abstracción puede

El diseño de sistemas y el diseño de procesos comerciales pueden usar esto. Algunos procesos de diseño generan específicamente diseños que contienen varios niveles de abstracción.

La arquitectura en capas divide las preocupaciones de la aplicación en grupos apilados (capas). Es una técnica utilizada en el diseño de software, hardware y comunicaciones de computadora en la que los componentes del sistema o de la red se aíslan en capas para que se puedan realizar cambios en una capa sin afectar a las demás.