Composition (programmation)

En programmation informatique, la composition est une technique qui permet de combiner plusieurs éléments de programmation entre eux pour obtenir un élément ayant une fonctionnalité plus complexe. On distingue la composition de fonctions, la composition d'objets, et la composition dans les modèles.

Composition de fonctions

La composition de fonctions consiste à définir une nouvelle fonction en combinant plusieurs fonctions entre elles[1].

Ce procédé s'inspire directement de la composition de fonctions en mathématiques, où le résultat d'une fonction est utilisé comme paramètre d'une autre. Deux fonctions et telles que et peuvent par exemple être combinées en une fonction telle que . En programmation procédurale, cette composition peut s'exprimer en une suite d'instructions:

double h(double x)
{
    double y = g(x);
    double z = f(y);
    return z;
}

Elle peut aussi combiner les expressions en une forme plus compacte[2], ce qui en facilite la maintenance[3]:

double h(double x)
{
    return f(g(x));
}

Certains langages de programmation fonctionnelle comme F# offrent des opérateurs pour composer des fonctions de cette manière[4]:

let h = g >> f

Dans le domaine de la programmation, la composition de fonction désigne par extension toute forme de combinaison de fonctions ou de procédures.

Composition d'objets

La programmation orientée objet se base sur le concept d'objets et le principe de l'encapsulation pour structurer les données et les opérations associées. La composition d'objet consiste alors à définir des objets ou des types composés en combinant des objets ou des types plus simples tout en respectant leur interface et en ignorant tout de leur fonctionnement interne[5].

La composition se distingue du mécanisme de l'héritage dans les langages à base de classes : l'héritage consiste à spécialiser des classes en leur ajoutant des éléments supplémentaires et en redéfinissant certains comportements. La classe d'un objet est déterminée au moment de sa création (on dit que l'objet est une instance de la classe) et l'objet ne peut pas changer de classe après sa création. La composition d'objets reste par contre dynamique : chaque composant est susceptible d'être remplacé à tout moment par un composant d'une classe compatible.

La composition se distingue également du mécanisme de prototypage utilisée par des langages orientés prototypes comme JavaScript : un nouvel objet créé à partir d'un prototype en hérite les compositions du prototype mais peut lui-même faire l'objet de compositions supplémentaires.

Modélisation conceptuelle

symbole graphique de la Composition dans les diagrammes de la modélisation UML.

La composition d'objets peut mettre en œuvre au niveau de la programmation des propriétés et des relations d'association, d'agrégation ou de composition d'un modèle de classes en UML. Au niveau conceptuel la composition a toutefois un sens plus restrictif[6].

Un lien de composition symbolise l'existence d'une agrégation particulière, dite 'forte', entre deux entités (classes).

Une composition est définie par les points suivants :

Durée de vie : toute classe agrégée est détruite quand la classe composite est détruite.
Exclusivité : une classe agrégée ne peut l'être que par une seule classe composite.
Notion de « fait partie de ».

La classe Voiture est une classe composite composée d'un élément de la classe Carburateur (un carburateur). La classe Carburateur est une classe agrégée. Quand une instance de la classe Voiture (une voiture) est détruite (dans un accident par exemple), le carburateur (instance de la classe Carburateur) aussi. Le carburateur fait partie de la voiture.

À noter que la distinction entre composition et agrégation n'est pas absolue : c'est le contexte qui détermine ce choix. Ainsi une voiture peut être vue comme l'agrégation d'un habitacle et 4 roues du point de vue d'un logiciel de casse automobile (la destruction de la voiture n'entrainera pas celle des roues si elles sont récupérées auparavant), ou bien comme une composition du point de vue d'un logiciel de simulation de comportement routier (où les roues nécessitent d'être traitées comme des entités distinctes, mais où le véhicule reste considéré comme un tout).

En UML, la composition se représente par un trait plein orné d'un losange noir du côté de la classe composite.

Exemple de code en C++

// Composition
class Voiture
{
  private :
    // Tout objet de type Voiture est responsable de l'attribut 'carbu', lequel est un objet de type Carburateur. 
    // Quand un objet de type Voiture est créé, son attribut 'carbu' est créé automatiquement. 
    // Quand un objet de type Voiture est détruit, son attribut 'carbu' est également détruit.
    Carburateur carbu;
  public :
    const Carburateur & getCarbu() const { // Méthode accesseur pour accéder en lecture seule à l'attribut 'carbu'
      return carbu;
    }
    void setCarbu(const Carburateur & unCarbu) { // Méthode mutateur pour initialiser l'attribut 'carbu'
      carbu = unCarbu;
    }
};

Notes et références

  1. (en) Donald B. McIntyre, « The role of composition in computer programming », ACM SIGAPL APL Quote Quad, vol. 25, no 4,‎ , p. 116–133 (ISSN 0163-6006, DOI 10.1145/206944.206985, lire en ligne, consulté le )
  2. (en) Cox, Brad, Object-oriented programming : an evolutionary approach, Addison-Wesley Pub. Co, , 15-17 p. (ISBN 0-201-54834-8 et 978-0-201-54834-1, OCLC 22767291, lire en ligne)
  3. (en) DeMarco, Tom., Why does software cost so much? : and other puzzles of the Information Age, Dorset House Pub, , 133-135 p. (ISBN 0-932633-34-X et 978-0-932633-34-7, OCLC 32922371, lire en ligne)
  4. (en) Microsoft, « Functions F# - Function composition and pipelining », sur docs.microsoft.com (consulté le )
  5. (en) Gamma, Erich., Helm, Richard, Johnson, Ralph E., et Vlissides, John., Design patterns : elements of reusable object-oriented software, Addison-Wesley, (ISBN 0-201-63361-2 et 978-0-201-63361-0, OCLC 31171684, lire en ligne)
  6. (en) OMG, « Unified Modeling Language Specification Version 2.5.1 », sur www.omg.org, (consulté le ), p. 109-110,197-201