stringtranslate.com

Composición de objetos

En informática , la composición de objetos y la agregación de objetos son formas estrechamente relacionadas de combinar objetos o tipos de datos para formar otros más complejos. En la conversación, la distinción entre composición y agregación a menudo se ignora. [1] Los tipos comunes de composiciones son los objetos utilizados en la programación orientada a objetos , las uniones etiquetadas , los conjuntos , las secuencias y varias estructuras gráficas . Las composiciones de objetos se relacionan con las estructuras de datos, pero no son lo mismo.

La composición de objetos se refiere a la estructura lógica o conceptual de la información, no a la implementación o estructura física de datos utilizada para representarla [ cita requerida ] . Por ejemplo, una secuencia difiere de un conjunto porque (entre otras cosas) el orden de los elementos compuestos importa para la primera pero no para el segundo. Las estructuras de datos como matrices , listas enlazadas , tablas hash y muchas otras se pueden utilizar para implementar cualquiera de ellas. Quizás de manera confusa, algunos de los mismos términos se utilizan tanto para las estructuras de datos como para los compuestos. Por ejemplo, " árbol binario " puede referirse a cualquiera de los dos: como estructura de datos es un medio para acceder a una secuencia lineal de elementos, y las posiciones reales de los elementos en el árbol son irrelevantes (el árbol se puede reorganizar internamente como uno quiera, sin cambiar su significado). Sin embargo, como composición de objetos, las posiciones son relevantes, y cambiarlas cambiaría el significado (como por ejemplo en los cladogramas ) [ cita requerida ] .

Técnica de programación

La programación orientada a objetos se basa en el uso de objetos para encapsular datos y comportamientos. Utiliza dos técnicas principales para ensamblar y componer funcionalidades en otras más complejas: la subtipificación y la composición de objetos. [2] La composición de objetos consiste en combinar objetos dentro de objetos compuestos y, al mismo tiempo, garantizar la encapsulación de cada objeto mediante el uso de su interfaz bien definida sin visibilidad de sus componentes internos. En este sentido, la composición de objetos se diferencia de las estructuras de datos, que no imponen la encapsulación.

La composición de objetos también puede tratarse de un grupo de múltiples objetos relacionados, como un conjunto o una secuencia de objetos. La delegación puede enriquecer la composición reenviando las solicitudes o llamadas realizadas al objeto compuesto que lo contiene a uno de sus componentes internos. [3]

En los lenguajes de programación tipados y basados ​​en clases , los tipos se pueden dividir en tipos compuestos y no compuestos, y la composición se puede considerar como una relación entre tipos: un objeto de un tipo compuesto (por ejemplo, coche ) " tiene " objetos de otros tipos (por ejemplo, rueda ). Cuando un objeto compuesto contiene varios subobjetos del mismo tipo, se les pueden asignar roles particulares , a menudo distinguidos por nombres o números. Por ejemplo, un objeto Punto puede contener 3 números, cada uno de los cuales representa la distancia a lo largo de un eje diferente, como 'x', 'y' y 'z'. El estudio de las relaciones parte-todo en general, es mereología .

La composición debe distinguirse de la subtipificación , que es el proceso de agregar detalles a un tipo de datos general para crear un tipo de datos más específico. Por ejemplo, los automóviles pueden ser un tipo específico de vehículo: el automóvil es un vehículo . La subtipificación no describe una relación entre diferentes objetos, sino que dice que los objetos de un tipo son simultáneamente objetos de otro tipo. El estudio de tales relaciones es la ontología .

En lenguajes de programación basados ​​en prototipos como JavaScript , los objetos pueden heredar dinámicamente los comportamientos de un objeto prototipo en el momento de su instanciación. La composición debe distinguirse de la creación de prototipos: el objeto recién instanciado hereda la composición de su prototipo, pero puede estar compuesto por sí mismo.

Los objetos compuestos se pueden representar en el almacenamiento mediante la ubicación conjunta de los objetos compuestos, mediante la ubicación conjunta de referencias o de muchas otras maneras. Los elementos dentro de un objeto compuesto se pueden denominar atributos , campos , miembros , propiedades u otros nombres, y la composición resultante se puede denominar tipo compuesto , registro de almacenamiento , estructura , tupla o tipo definido por el usuario (UDT) . Para obtener más detalles, consulte la sección de agregación a continuación.

Técnica de modelado UML

Una clase de bicicleta representada en UML, con tres propiedades: sillín, ruedas y piezas, las dos últimas con una multiplicidad que indica varios objetos.
Composición de objetos utilizando propiedades UML para componer objetos

En el modelado UML , los objetos pueden ser compuestos conceptualmente, independientemente de su implementación con un lenguaje de programación. Existen cuatro formas de componer objetos en UML: propiedad, asociación, agregación y composición: [4]

La relación entre el agregado y sus componentes es una relación débil del tipo "tiene un": los componentes pueden ser parte de varios agregados, se puede acceder a ellos a través de otros objetos sin pasar por el agregado y pueden sobrevivir al objeto agregado. [4] El estado del objeto componente todavía forma parte del objeto agregado. [ cita requerida ]

La relación entre el compuesto y sus partes es una fuerte relación de “tiene un”: el objeto compuesto tiene la “ responsabilidad exclusiva de la existencia y almacenamiento de los objetos compuestos ”, el objeto compuesto puede ser parte de, como máximo, un compuesto y “ si se elimina un objeto compuesto, todas las instancias de sus partes que son objetos se eliminan con él ”. Por lo tanto, en UML, composición tiene un significado más limitado que la composición de objetos habitual.

Asociación entre varias bicicletas que tienen cada una un propietario; Composición de una bicicleta con partes del cuadro que forman la bicicleta; y agregación de una bicicleta con sus ruedas, que existen sin la bicicleta
Notación UML para asociación, composición y agregación

La notación gráfica representa:

Agregación

La agregación se diferencia de la composición ordinaria en que no implica propiedad. En la composición, cuando se destruye el objeto propietario, también se destruyen los objetos que contiene. En la agregación, esto no es necesariamente cierto. Por ejemplo, una universidad posee varios departamentos (por ejemplo, química ), y cada departamento tiene un número de profesores. Si la universidad cierra, los departamentos ya no existirán, pero los profesores de esos departamentos seguirán existiendo. Por lo tanto, una universidad puede verse como una composición de departamentos, mientras que los departamentos tienen una agregación de profesores. Además, un profesor podría trabajar en más de un departamento, pero un departamento no podría ser parte de más de una universidad.

La composición suele implementarse de forma que un objeto contenga otro objeto. Por ejemplo, en C++ :

Clase Profesor ; // Definido en otra parte  clase Departamento { público : Departamento ( const std :: string & título ) : título_ ( título ) {}         privado : // Agregación: Los |Profesores| pueden sobrevivir al |Departamento|. std :: vector < std :: weak_ptr < Profesor >> miembros_ ; const std :: string título_ ; };      clase Universidad { public : Universidad () = default ;       privado : // Composición: Los departamentos solo existen mientras exista la facultad. std :: vector < Departamento > facultad_ = { Departamento ( "química" ), Departamento ( "física" ), Departamento ( "artes" ), } ; };         

En agregación, el objeto solo puede contener una referencia o puntero al objeto (y no tener responsabilidad de por vida sobre él).

A veces se hace referencia a la agregación como composición cuando la distinción entre composición ordinaria y agregación no es importante.

El código anterior se transformaría en el siguiente diagrama de clases UML:

Agregación en COM

Agregación en COM

En el Modelo de objetos componentes de Microsoft , la agregación significa que un objeto exporta, como si fuera su propietario, una o varias interfaces de otro objeto que posee. Formalmente, esto es más similar a la composición o encapsulación que a la agregación. Sin embargo, en lugar de implementar las interfaces exportadas llamando a las interfaces del objeto propio, se exportan las interfaces del objeto propio. El objeto propio es responsable de asegurar que los métodos de esas interfaces heredadas de IUnknown realmente invoquen los métodos correspondientes del propietario. Esto es para garantizar que el recuento de referencias del propietario sea correcto y que todas las interfaces del propietario sean accesibles a través de la interfaz exportada, mientras que ninguna otra interfaz (privada) del objeto propio sea accesible. [5]

Formularios especiales

Contención

La composición que se utiliza para almacenar varias instancias del tipo de datos compuesto se denomina contenedor. Algunos ejemplos de estos contenedores son las matrices , las matrices asociativas , los árboles binarios y las listas enlazadas .

En UML , la contención se representa con una multiplicidad de 0..* o 1..*, lo que indica que el objeto compuesto está formado por un número desconocido de instancias de la clase compuesta.

Composición recursiva

Los objetos se pueden componer de forma recursiva y su tipo se denomina tipo recursivo . Entre los ejemplos se incluyen varios tipos de árboles , DAG y grafos . Cada nodo de un árbol puede ser una rama o una hoja; en otras palabras, cada nodo es un árbol al mismo tiempo que pertenece a otro árbol.

En UML, la composición recursiva se representa con una asociación, agregación o composición de una clase consigo misma.

Patrón compuesto

El patrón de diseño compuesto es un diseño orientado a objetos basado en tipos compuestos, que combina composición recursiva y contención para implementar jerarquías complejas de parte-todo.

Tipos compuestos en C

Este es un ejemplo de composición en C.

struct Persona { int edad ; char nombre [ 20 ]; enum { búsqueda_de_empleo , profesional , no_profesional , jubilado , estudiante } empleo ; };            

En este ejemplo, los tipos primitivos (no compuestos) int , enum {job_seeking, professional, non_professional, retired, student } y el tipo de matriz compuesto char[] se combinan para formar la estructura compuesta Person . Cada estructura Person "tiene" una edad, un nombre y un tipo de empleo.

Cronología de la composición en varios idiomas

C llama a un registro una estructura ; los lenguajes orientados a objetos como Java , Smalltalk y C++ a menudo mantienen sus registros ocultos dentro de objetos ( instancias de clase ); los lenguajes de la familia ML simplemente los llaman registros. COBOL fue el primer lenguaje de programación generalizado que admitió registros directamente; [6] ALGOL 68 lo obtuvo de COBOL y Pascal lo obtuvo, más o menos indirectamente, de ALGOL 68. Common Lisp proporciona estructuras y clases (estas últimas a través del Common Lisp Object System ). [ cita requerida ]

1959 – COBOL
 01 registro-cliente . 03 número-cliente pic 9(8) comp . 03 nombre-cliente . 05 nombres-de-pila pic x(15) . 05 inicial-2 pic x . 05 apellido pic x(15) . 03 dirección-cliente . 05 calle . 07 nombre-calle pic x(15) . 09 número-casa pic 999 comp . 05 ciudad pic x(10) . 05 código-país pic x(3) . 05 código postal pic x(8) . 03 importe-adeudado pic 9(8) comp .                                       
1960 – ALGOL 60

Las matrices eran el único tipo de datos compuestos en Algol 60 .

1964 – PL/I
dcl 1 basado en newtypet (P); 2 (a, b, c) contenedor fijo (31), 2 (i, j, k) flotan, 2 r ptr;asignar newtypet;
1968 – ALGOL 68
int máximo = 99;modo newtypet = [0..9] [0..max]struct ( largo real a, b, c, corto int i, j, k, ref real r);newtypet newarrayt = (1, 2, 3, 4, 5, 6, montón real := 7)

Por ejemplo, una lista enlazada podría declararse como:

modo nodo = unión (real, int, compl, cadena), lista = struct (nodo val, ref lista siguiente);

En el caso de ALGOL 68, solo el nombre del tipo aparece a la izquierda de la igualdad y, lo más notable, la construcción se realiza (y puede leerse) de izquierda a derecha sin tener en cuenta las prioridades.

1970 – Pascual
tipo a = matriz [ 1 .. 10 ] de enteros ; b = registro a , b , c : real ; i , j , k : entero ; fin ;                  
1972 – K&R C
#define max 99 struct newtypet { double a , b , c ; float r ; short i , j , k ; } newarrayt [ 10 ] [ max + 1 ];                
1977 – FORTRAN 77

Fortran 77 tiene matrices, pero no tenía definiciones formales de registros o estructuras. Normalmente, las estructuras compuestas se creaban utilizando instrucciones EQUIVALENCE o COMMON :

 NOMBRE DEL PERSONAJE * 32 , DIRECCIÓN * 32 , TELÉFONO * 16 REAL DEBIDO COMÚN / CLIENTE / NOMBRE , DIRECCIÓN , TELÉFONO , DEBIDO        
1983 – Ada
tipo  Cust  es  registro  Nombre  :  Nombre_Tipo ;  Direccion  :  Direccion_Tipo ;  Telefono  :  Telefono_Tipo ;  Deudor  :  Rango entero  1. . 999999 ; fin registro ;  

Ada 95 incorporó conceptos de programación orientada a objetos a través de tipos etiquetados (el equivalente a una clase C++) y Ada 2012 agregó soporte para la verificación de sustitución a través de contratos de toda la clase.

1983 – C++
const int max = 99 ; clase { público : doble a , b , c ; flotante & r ; corto i , j , k ; } newtypet [ 10 ] [ max + 1 ];                   
1991 – Pitón
max  =  99 clase  NewTypeT :  def  __init__ ( self ):  self . a  =  self . b  =  self . c  =  0  self . i  =  self . j  =  self . k  =  0.0 # Inicializa una matriz de ejemplo de esta clase. newarrayt  =  [[ NewTypeT ()  para  i  en  rango ( max  +  1 )]  para  j  en  rango ( 10 )]
1992 – FORTRAN 90

Las matrices y cadenas se heredaron de FORTRAN 77 y se introdujo una nueva palabra reservada: type

tipo newtypet doble precisión a , b , c entero * 2 i , j , k * Sin tipo de puntero REF REAL R tipo final           tipo ( newtypet ) t ( 10 , 100 )   

FORTRAN 90 se actualizó e incluyó el concepto de FORTRAN IV llamado NAMELIST.

INTEGER :: ene = 1 , feb = 2 , mar = 3 , abr = 4 LISTA DE NOMBRES / semana / ene , feb , mar , abr                    
1994 – ANSI Common Lisp

Common Lisp proporciona estructuras y el estándar ANSI Common Lisp agregó clases CLOS.

( defclass alguna-clase () (( f :tipo float ) ( i :tipo entero ) ( a :tipo ( matriz entero ( 10 )))))             

Para obtener más detalles sobre la composición en C/C++, consulte Tipo compuesto .

Véase también

Referencias

  1. ^ Yaiser, Michelle. "Conceptos de programación orientada a objetos: composición y agregación". Archivado desde el original el 8 de abril de 2015. Existe un concepto estrechamente relacionado con la composición llamado agregación. En la conversación, las diferencias entre composición y agregación a menudo se ignoran.
  2. ^ Patrones de diseño: elementos de software orientado a objetos reutilizable. Gamma, Erich., Helm, Richard (informático), Johnson, Ralph E., 1955-, Vlissides, John. Reading, Mass.: Addison-Wesley. 1995. ISBN 0-201-63361-2.OCLC 31171684  .{{cite book}}: Mantenimiento de CS1: otros ( enlace )
  3. ^ Ostermann, Klaus; Mezini, Mira (1 de octubre de 2001). "Composición orientada a objetos desenredada". ACM SIGPLAN Notices . 36 (11): 283–299. doi :10.1145/504311.504303. ISSN  0362-1340.
  4. ^ ab OMG (2017). "Unified Modeling Language Specification Version 2.5.1". www.omg.org . p. 109-110,197-201 . Consultado el 4 de octubre de 2020 .
  5. ^ "Agregación". SDK de plataforma para Windows XP SP2 . Microsoft . Consultado el 4 de noviembre de 2007 .
  6. ^ Sebesta, Robert W. Conceptos de lenguajes de programación (tercera edición). Addison-Wesley Publishing Company, Inc. pág. 218. ISBN 0-8053-7133-8.

Enlaces externos