Article de reference

Composition d'objet

En informatique , la composition d'objets et l'agrégation d'objets sont des méthodes étroitement liées pour combiner des objets ou des types de données en objets plus complexes....

En informatique , la composition d'objets et l'agrégation d'objets sont des méthodes étroitement liées pour combiner des objets ou des types de données en objets plus complexes. Dans la conversation, la distinction entre composition et agrégation est souvent ignorée. Les types courants de compositions sont les objets utilisés dans la programmation orientée objet , les unions étiquetées , les ensembles , les séquences et diverses structures de graphes . Les compositions d'objets sont liées aux structures de données, mais ne sont pas identiques à celles-ci.

La composition d'objets fait référence à la structure logique ou conceptuelle de l'information, et non à la mise en œuvre ou à la structure de données physique utilisée pour la représenter . Par exemple, une séquence diffère d'un ensemble parce que (entre autres choses) l'ordre des éléments composés importe pour la première mais pas pour la seconde. Des structures de données telles que des tableaux , des listes chaînées , des tables de hachage et bien d'autres peuvent être utilisées pour implémenter l'une ou l'autre d'entre elles. Peut-être de manière déroutante, certains des mêmes termes sont utilisés à la fois pour les structures de données et les composites. Par exemple, « arbre binaire » peut faire référence à l'un ou l'autre : en tant que structure de données, c'est un moyen d'accéder à une séquence linéaire d'éléments, et les positions réelles des éléments dans l'arbre ne sont pas pertinentes (l'arbre peut être réorganisé en interne comme on le souhaite, sans changer sa signification). Cependant, en tant que composition d'objets, les positions sont pertinentes, et les changer changerait la signification (comme par exemple dans les cladogrammes ) .

Technique de programmation

La programmation orientée objet repose sur l'utilisation d'objets pour encapsuler des données et des comportements. Elle utilise deux techniques principales pour assembler et composer des fonctionnalités en des fonctionnalités plus complexes, le sous-typage et la composition d'objets. La composition d'objets consiste à combiner des objets au sein d'objets composés et, en même temps, à assurer l'encapsulation de chaque objet en utilisant leur interface bien définie sans visibilité de leurs éléments internes. À cet égard, la composition d'objets diffère des structures de données, qui n'imposent pas l'encapsulation.

La composition d'objets peut également concerner un groupe de plusieurs objets liés, comme un ensemble ou une séquence d'objets. La délégation peut enrichir la composition en transmettant les requêtes ou les appels effectués à l'objet composite englobant à l'un de ses composants internes.

Dans les langages de programmation typés et basés sur les classes , les types peuvent être divisés en types composites et non composites, et la composition peut être considérée comme une relation entre les types : un objet d'un type composite (par exemple, car ) « possède » des objets d'autres types (par exemple, wheel ). Lorsqu'un objet composite contient plusieurs sous-objets du même type, ils peuvent être assignés à des rôles particuliers , souvent distingués par des noms ou des numéros. Par exemple, un objet Point peut contenir 3 nombres, chacun représentant une distance le long d'un axe différent, tel que « x », « y » et « z ». L'étude des relations partie-tout en général est la méréologie .

La composition doit être distinguée du sous-typage , qui est le processus d'ajout de détails à un type de données général pour créer un type de données plus spécifique. Par exemple, cars peut être un type de véhicule spécifique : car est un véhicule . Le sous-typage ne décrit pas une relation entre différents objets, mais indique plutôt que les objets d'un type sont simultanément des objets d'un autre type. L'étude de telles relations est l'ontologie .

Dans les langages de programmation basés sur des prototypes tels que JavaScript , les objets peuvent hériter dynamiquement des comportements d'un objet prototype au moment de leur instanciation. La composition doit être distinguée du prototypage : l'objet nouvellement instancié hérite de la composition de son prototype, mais il peut lui-même être composé de lui-même.

Les objets composites peuvent être représentés dans le stockage en regroupant les objets composés, en regroupant les références ou de bien d'autres manières. Les éléments d'un objet composite peuvent être appelés attributs , champs , membres , propriétés ou d'autres noms, et la composition résultante peut être appelée type composite , enregistrement de stockage , structure , tuple ou type défini par l'utilisateur (UDT) . Pour plus de détails, consultez la section agrégation ci-dessous.

Technique de modélisation UML

Une classe de vélo représentée en UML, avec trois propriétés : selle, roues et pièces, les deux dernières ayant une multiplicité indiquant plusieurs objets
Composition d'objets à l'aide de propriétés UML pour composer des objets

Dans la modélisation UML , les objets peuvent être composés conceptuellement, indépendamment de l'implémentation avec un langage de programmation. Il existe quatre façons de composer des objets dans UML : propriété, association, agrégation et composition :

  • Une propriété représente un attribut de la classe.
  • Une association représente une relation sémantique entre des instances de classes associées. L'extrémité membre d'une association correspond à une propriété de la classe associée.
  • Une agrégation est un type d'association qui modélise une relation partie/tout entre un agrégat (tout) et un groupe de composants connexes (parties).
  • Une composition, également appelée agrégation composite, est un type d'agrégation qui modélise une relation partie/tout entre un composite (tout) et un groupe de parties détenues exclusivement.

La relation entre l'agrégat et ses composants est une relation faible de type « a-a » : les composants peuvent faire partie de plusieurs agrégats, peuvent être accessibles via d'autres objets sans passer par l'agrégat et peuvent survivre à l'objet agrégat. L'état de l'objet composant fait toujours partie de l'objet agrégat.

La relation entre le composite et ses parties est une relation forte de type « possède un » : l'objet composite est seul « responsable de l'existence et du stockage des objets composés », l'objet composé ne peut faire partie que d'un seul composite et « si un objet composite est supprimé, toutes ses instances de parties qui sont des objets sont supprimées avec lui ». Ainsi, dans UML, la composition a une signification plus étroite que la composition d'objet habituelle.

Association entre plusieurs bicyclettes ayant chacune un propriétaire ; Composition d'une bicyclette avec des parties de cadre qui composent la bicyclette ; et agrégation d'une bicyclette avec ses roues, qui existent sans la bicyclette
Notation UML pour l'association, la composition et l'agrégation

La notation graphique représente :

  • la propriété en tant qu'élément typé dans la boîte de la classe englobante,
  • l'association comme une ligne simple entre les classes associées,
  • l'agrégation sous forme de losange non rempli sur le côté de l'agrégat et d'une ligne continue,
  • la composition comme un losange rempli sur le côté du composite et une ligne continue.

Agrégation

L'agrégation diffère de la composition ordinaire en ce qu'elle n'implique pas de propriété. Dans la composition, lorsque l'objet propriétaire est détruit, les objets contenus le sont également. Dans l'agrégation, ce n'est pas nécessairement vrai. Par exemple, une université possède plusieurs départements (par exemple, la chimie ), et chaque département compte un certain nombre de professeurs. Si l'université ferme, les départements n'existeront plus, mais les professeurs de ces départements continueront d'exister. Par conséquent, une université peut être considérée comme une composition de départements, alors que les départements ont une agrégation de professeurs. De plus, un professeur peut travailler dans plusieurs départements, mais un département ne peut pas faire partie de plusieurs universités.

La composition est généralement implémentée de telle sorte qu'un objet contienne un autre objet. Par exemple, en C++ :

classe Professeur ; // Défini ailleurs
classe Département { public : Département ( const std :: chaîne & titre ) : titre_ ( titre ) {}
privé : 
// Agrégation : |Les professeurs| peuvent survivre au |Département|. std :: vector < std :: weak_ptr < Professeur >> members_ ; const std :: string title_ ; };
classe Université { public : Université () = par défaut ;
privé : 
// Composition : les |départements| n'existent que tant que la faculté existe. std :: vector < Département > faculté_ = { Département ( "chimie" ), Département ( "physique" ), Département ( "arts" ), }; };

Lors de l'agrégation, l'objet ne peut contenir qu'une référence ou un pointeur vers l'objet (et ne pas en avoir la responsabilité à vie ).

Parfois, l’agrégation est appelée composition lorsque la distinction entre composition ordinaire et agrégation n’est pas importante.

Le code ci-dessus se transformerait en le diagramme de classes UML suivant :

Agrégation dans COM

Agrégation dans COM

Dans le modèle d'objet composant de Microsoft , l'agrégation signifie qu'un objet exporte, comme s'il était son propriétaire, une ou plusieurs interfaces d'un autre objet qu'il possède. Formellement, cela ressemble plus à la composition ou à l'encapsulation qu'à l'agrégation. Cependant, au lieu d'implémenter les interfaces exportées en appelant les interfaces de l'objet possédé, les interfaces de l'objet possédé elles-mêmes sont exportées. L'objet possédé est chargé de s'assurer que les méthodes de ces interfaces héritées de IUnknown invoquent réellement les méthodes correspondantes du propriétaire. Cela permet de garantir que le décompte de références du propriétaire est correct et que toutes les interfaces du propriétaire sont accessibles via l'interface exportée, tandis qu'aucune autre interface (privée) de l'objet possédé n'est accessible.

Formes spéciales

Endiguement

La composition utilisée pour stocker plusieurs instances du type de données composite est appelée « confinement ». Les exemples de tels conteneurs sont les tableaux , les tableaux associatifs , les arbres binaires et les listes chaînées .

En UML , le confinement est représenté par une multiplicité de 0..* ou 1..*, indiquant que l'objet composite est composé d'un nombre inconnu d'instances de la classe composée.

Composition récursive

Les objets peuvent être composés de manière récursive, et leur type est alors appelé type récursif . Les exemples incluent différents types d' arbres , de DAG et de graphes . Chaque nœud d'un arbre peut être une branche ou une feuille ; en d'autres termes, chaque nœud est un arbre en même temps qu'il appartient à un autre arbre.

En UML, la composition récursive est représentée par une association, une agrégation ou une composition d'une classe avec elle-même.

Motif composite

Le modèle de conception composite est une conception orientée objet basée sur des types composites, qui combine la composition récursive et le confinement pour implémenter des hiérarchies complexes de parties et de tout.

Types composites en C

Ceci est un exemple de composition en C .

struct Person { int age ; char name [ 20 ]; enum { recherche_d'emploi , professionnel , non_professionnel , retraité , étudiant } emploi ; };

Dans cet exemple, les types primitifs (non composites) int , enum {job_seeking, professional, non_professional, retired, student } et le type de tableau composite char[] sont combinés pour former la structure composite Person . Chaque structure Person « possède » alors un âge, un nom et un type d'emploi.

Chronologie de la composition en différentes langues

C appelle un enregistrement une structure ou struct ; les langages orientés objet tels que Java , Smalltalk et C++ gardent souvent leurs enregistrements cachés à l'intérieur d'objets ( instances de classe ) ; les langages de la famille ML les appellent simplement enregistrements. COBOL a été le premier langage de programmation répandu à prendre en charge directement les enregistrements ; ALGOL 68 l'a obtenu de COBOL et Pascal l'a obtenu, plus ou moins indirectement, d'ALGOL 68. Common Lisp fournit des structures et des classes (ces dernières via le Common Lisp Object System ).

1959 – COBOL
01 dossier-client . 
03 numéro-client pic 9(8) comp . 03 nom-client . 05 prénoms pic x(15) . 05 initiale-2 pic x . 05 nom-de-famille pic x(15) . 03 adresse-client . 05 rue . 07 nom-de-rue pic x(15) . 09 numéro-de-maison pic 999 comp . 05 ville pic x(10) . 05 code-pays pic x(3) . 05 code postal pic x(8) . 03 montant-dû pic 9(8) comp .
1960 – ALGOL 60

Les tableaux étaient le seul type de données composite dans Algol 60 .

1964 – PL/I
dcl 1 basé sur newtypet (P) ; 2 (a, b, c) bac fixe (31), 2 (i, j, k) flottant, 2 r ptr; allouer un nouveau type ; 
1968 – ALGOL 68
int max = 99; mode nouveautypet = [0..9] [0..max]struct ( long réel a, b, c, court int i, j, k, ref réel r ); newtypet newarrayt = (1, 2, 3, 4, 5, 6, tas réel := 7) 

Par exemple, une liste chaînée peut être déclarée comme suit :

mode nœud = union (réel, int, compl, chaîne), liste = struct (noeud val, ref liste suivante); 

Pour ALGOL 68, seul le nom du type apparaît à gauche de l'égalité et, plus particulièrement, la construction est réalisée – et peut être lue – de gauche à droite sans tenir compte des priorités.

1970 – Pascal
type 
a = tableau [ 1 .. 10 ] d' entiers ; b = enregistrement a , b , c : réel ; i , j , k : entier ; 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 possède des tableaux, mais ne contient aucune définition formelle d'enregistrement/structure. En général, les structures composées sont construites à l'aide d'instructions EQUIVALENCE ou COMMON :

NOM DU PERSONNAGE * 32 , ADDR * 32 , TÉLÉPHONE * 16 RÉEL COMMUN / CLIENT / NOM , ADDR , TÉLÉPHONE , 
1983 – Ada
type 
Cust 
est 
un enregistrement 
Nom 
: 
Nom_Type ; 
Addr 
: 
Addr_Type ; 
Téléphone 
: 
Téléphone_Type ; 
Devoir 
: 
Plage d'entiers 
1. . 999999 ; fin de l'enregistrement ;

Ada 95 a apporté des concepts OOP via des types balisés (l'équivalent d'une classe C++), Ada 2012 a ajouté la prise en charge de la vérification de substitution via des contrats à l'échelle de la classe.

1983 – C++
const int max = 99 ; classe { public : double a , b , c ; float & r ; court i , j , k ; } newtypet [ 10 ] [ max + 1 ];
1991 – Python
max 
= 
99 
class 
NewTypeT : 
def 
__init__ ( self ): 
self . a 
= 
self . b 
= 
self . c 
= 
0 
self . i 
= 
self . j 
= 
self . k 
= 
0.0 
# Initialiser un exemple de tableau de cette classe. 
newarrayt 
= 
[[ NewTypeT () 
pour 
i 
dans 
la plage ( max 
+ 
1 )] 
pour 
j 
dans 
la plage ( 10 )]
1992 – FORTRAN 90

Les tableaux et les chaînes ont été hérités du FORTRAN 77, et un nouveau mot réservé a été introduit : type

type newtypet 
double précision a , b , c entier * 2 i , j , k * Pas de type pointeur REF REAL R fin de type
type ( nouveautype ) t ( 10 , 100 )

FORTRAN 90 a été mis à jour et inclut le concept de FORTRAN IV appelé NAMELIST.

INTEGER : jan = 1 , février = 2 , mars = 3 , avril = 4 NAMELIST / semaine / janvier , février , mars , avril
1994 – ANSI Common Lisp

Common Lisp fournit des structures et la norme ANSI Common Lisp a ajouté des classes CLOS.

( defclass some-class () (( f :type float ) ( i :type entier ) ( a :type ( tableau entier ( 10 )))))

Pour plus de détails sur la composition en C/C++, voir Type composite .

Plus d articles de Worldlex Wiki

Revenez a l index pour explorer davantage de pages sur l histoire, la science, la culture, la geographie et la societe en francais.

Explorer l index