Composition de l'objet - Object composition

En informatique , la composition d'objets est un moyen de combiner des objets ou des types de données en des types plus complexes. 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 se rapportent aux structures de données, mais ne sont pas identiques.

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) l'ordre des éléments composés importe pour le premier mais pas pour le dernier. 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. Peut-être déroutant, certains des mêmes termes sont utilisés à la fois pour les structures de données et les composites. Par exemple, " arbre binaire " peut désigner soit: en tant que structure de données, il s'agit d'un moyen d'accéder à une séquence linéaire d'éléments, et les positions réelles des éléments dans l'arborescence ne sont pas pertinentes (l'arbre peut être réorganisé en interne comme on veut, sans en changer le sens). Cependant, en tant que composition d'objets, les positions sont pertinentes, et les changer en changerait le sens (comme par exemple dans les cladogrammes ).

Technique de programmation

La programmation orientée objet est basée sur des objets pour encapsuler les données et le comportement. Il utilise deux techniques principales pour assembler et composer des fonctionnalités en des techniques 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, tels qu'un ensemble ou une séquence d'objets. La délégation peut enrichir la composition en transférant les demandes ou les appels faits à l'objet composite englobant vers l'un de ses composants internes.

Dans les langages de programmation basés sur les classes et typés , 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 voiture ) " a " des objets d'autres types ( ex. roue ). Lorsqu'un objet composite contient plusieurs sous-objets du même type, ils peuvent être affecté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 la distance le long d'un axe différent, tel que « x », « y » et « z ». L'étude des relations partie-tout en général, c'est la méréologie .

La composition doit être distinguée du sous - typage , qui consiste à ajouter des détails à un type de données général pour créer un type de données plus spécifique. Par exemple, les voitures peuvent être un type de véhicule spécifique : la voiture 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 une 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 co-localisant les objets composés, en co-localisant des références, ou de nombreuses autres manières. Les éléments d'un objet composite peuvent être appelés attributs , champs , membres , propriétés ou autres noms, et la composition résultante en tant que type composite , enregistrement de stockage , structure , tuple ou type défini par l' utilisateur (UDT) . Pour plus de détails, consultez la section sur l' 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 de manière conceptuelle, indépendamment de l'implémentation avec un langage de programmation. Il existe quatre manières de composer des objets en 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 les instances des classes associées. L'extrémité membre d'une association correspond à une propriété de la classe associée.
  • Une agrégation est une sorte d'association qui modélise une relation partie/tout entre un agrégat (tout) et un groupe de composants liés (parties).
  • Une composition, également appelée agrégation composite, est une sorte d'agrégation qui modélise une relation partie/tout entre un composite (tout) et un groupe de parties détenues en exclusivité.

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

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

Association entre plusieurs vélos ayant chacun un propriétaire ;  Composition d'un vélo avec des pièces de cadre qui font le vélo ;  et agrégation d'un vélo avec ses roues, qui existent sans le vélo
Notation UML pour l'association, la composition et l'agrégation

La notation graphique représente :

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


Formes spéciales

Endiguement

La composition utilisée pour stocker plusieurs instances du type de données composite est appelée confinement. Des 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é avec 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 divers types d' arbres , de DAG et de graphiques . 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 lorsqu'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 partie-tout complexes.

Types composites en C

Ceci est un exemple de composition en C .

struct Person
{
  int age;
  char name[20];
  enum {job_seeking, professional, non_professional, retired, student} employment;
};

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

Chronologie de la composition en plusieurs langues

C appelle un enregistrement une struct ou une structure ; les langages orientés objet tels que Java , Smalltalk et C++ gardent souvent leurs enregistrements cachés dans des objets ( instances de classe ) ; les langues de la famille ML les appellent simplement des 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, de ALGOL 68. Common Lisp fournit des structures et des classes (ces dernières via le Common Lisp Object System ).

1959 – COBOL
      01  customer-record.
        03  customer-number     pic 9(8) comp.
        03  customer-name.
          05  given-names       pic x(15).
          05  initial-2         pic x.
          05  surname           pic x(15).
        03  customer-address.
          05  street.
            07  street-name     pic x(15).
              09  house-number  pic 999 comp.
          05  city              pic x(10).
          05  country-code      pic x(3).
          05  postcode          pic x(8).
        03  amount-owing        pic 9(8) comp.
1960 – ALGOL 60

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

1964 – PL/I
dcl 1 newtypet based (P);
 2 (a, b, c) fixed bin(31),
 2 (i, j, k) float,
 2 r ptr;
allocate newtypet;
1968 – ALGOL 68
int max = 99;
mode newtypet = [0..9] [0..max]struct (
 long real a, b, c, short int i, j, k, ref real r
);
newtypet newarrayt = (1, 2, 3, 4, 5, 6, heap real := 7)

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

mode node = union (real, int, compl, string),
 list = struct (node val, ref list next);

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

1970 – Pascal
type
 a = array [1..10] of integer;
 b = record
  a, b, c: real;
  i, j, k: integer;
 end;
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 a des tableaux, mais il manquait de définitions formelles d'enregistrement/de structure. Généralement, les structures composées ont été construites à l'aide d' instructions EQUIVALENCE ou COMMON :

       CHARACTER NAME*32, ADDR*32, PHONE*16
       REAL OWING
       COMMON /CUST/NAME, ADDR, PHONE, OWING
1983 – Ada
type Cust is
 record
  Name  : Name_Type;
  Addr  : Addr_Type;
  Phone : Phone_Type;
  Owing : Integer range 1..999999;
 end record;

Ada 95 a apporté des concepts de POO via des types étiqueté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;
class {
  public:
  double a, b, c;
  float &r;
  short 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
# Initialise an example array of this class.
newarrayt = [[NewTypeT() for i in range(max + 1)] for j in range(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 precision a, b, c
 integer*2 i, j, k
* No pointer type REF REAL R
 end type

type (newtypet) t(10, 100)

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

INTEGER :: jan = 1, feb = 2, mar = 3, apr = 4
NAMELIST / week / jan, feb, mar, apr
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 integer)
   (a :type (array integer (10)))))

Pour plus d'informations sur la composition en C / C ++, consultez Type composite .

Agrégation

L'agrégation diffère de la composition ordinaire en ce qu'elle n'implique pas la propriété. En composition, lorsque l'objet propriétaire est détruit, les objets contenus le sont aussi. En agrégation, ce n'est pas nécessairement vrai. Par exemple, une université possède divers départements (par exemple, chimie ), et chaque département a 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 plus d'un département, mais un département ne peut faire partie de plus d'une université.

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

class Professor;  // Defined elsewhere

class Department {
 public:
  Department(const std::string& title): title_(title) {}

 private:
  // Aggregation: |Professors| may outlive the |Department|.
  std::vector<std::weak_ptr<Professor>> members_;
  const std::string title_;
};


class University {
 public:
  University() = default;

 private:
  // Composition: |Department|s exist only as long as the faculty exists.
  std::vector<Department> faculty_ = {
      Department("chemistry"),
      Department("physics"),
      Department("arts"),
  };
};

Dans l'agrégation, l'objet peut uniquement contenir 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 la composition ordinaire et l'agrégation est sans importance.

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

Agrégation-Composition3.png

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 détenu, les interfaces de l'objet détenu elles-mêmes sont exportées. L'objet possédé est responsable 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 nombre de références du propriétaire est correct et que toutes les interfaces du propriétaire sont accessibles via l'interface exportée, alors qu'aucune autre interface (privée) de l'objet possédé n'est accessible.

Voir également

Les références

Liens externes