Page d'accueil encyclopedie-enligne.com en page d'accueil
Liste Articles: [0-A] [A-C] [C-F] [F-J] [J-M] [M-P] [P-S] [S-Z] | Liste Catégories | Une page au hasard | Pages liées

Programmation orientée objet


image:Langage_progr.png
Cet article fait partie de
la série Langages de programmation
Langages orientés objet
Ada 95 - C++ - C#
Common lisp object system
Delphi - Eiffel - Java - Nice
Langages impératifs
APL - ASP
Assembleur
BASIC - C - Pascal
Perl - PHP - Python
Langages fonctionnels
ML/OCaml - Lisp/Common Lisp
Forth - Logo - Scheme
Langages déclaratifs
Clips - Prolog
Voir aussi
Conception - Codage
Tests - Optimisations


Sommaire

Origines

La programmation orientée objet (POO) ou programmation à objets est née des travaux sur la mise au point de langages de simulation dans les années 1960 (par exemple Simula-67), et a été utilisée également dans le cadre de recherches sur l'intelligence artificielle dans les années 1970-80. Elle consiste à combiner au sein d'une même structure de données, appelée Classe, les opérations et données.

Pourquoi ?

Pour permettre plus facilement des modifications fondamentales dans la façon de représenter et de traiter les données.

Imaginons par exemple que nous souhaitions traiter des nombres complexes. Vaut-il mieux les représenter de façon cartésienne (x, y) ou polaire (angle, module)? Nous ne le saurons qu'en effectuant des statistiques dans l'application où nous les utiliserons, et nous ne pourrons effectuer ces statistiques qu'en créant justement un premier modèle opérationnel : il semble que nous soyons pris dans une autoréférence fâcheuse.

Si nous convenons que nous diposons d'une boîte noire que nous nommerons un objet « nombre complexe » et qu'il soit possible de lui affecter des valeurs en représentation polaire ou cartésienne, comme d'aller les lire en polaire ou en cartésien selon ce qui nous arrange le mieux, nous pouvons différer ce choix, et le changer à tout moment rien qu'en modifiant la définition de ce seul objet. Par comparaison, une approche classique aurait obligé à faire la chasse à toutes les références utilisant des nombres complexes et à en réécrire sans jamais rien omettre toutes les lectures et écritures là où cela était nécessaire. C'est ici le compilateur qui se chargera à notre place de ce travail (à moins que le langage objet ne soit interprété, comme Smalltalk, mais cela ne change rien à la flexibilité elle-même).

Le concept de classe a été introduit avec le langage Simula, ceux d'encapsulation, d'héritage et de polymorphisme avec le langage SmallTalk.

Depuis, l'Objet n'a cessé d'évoluer aussi bien dans son aspect théorique que pratique et différents métiers et discours mercatiques à son sujet ont vu le jour comme l'analyse objet (AOO ou OOA en anglais), la conception objet (COO ou OOD en anglais) ou banque de données objet (SGBDOO). Aujourd'hui, l'Objet est vu davantage comme une approche utile, un paradigme, qu'une simple technique de programmation (bien que les programmes objets soient également plus lisibles que les programmes classiques). C'est pourquoi, lorsque l'on parle de l'Objet, on le désigne plus volontiers comme approche Objet que par programmation à objets, cette dernière ne désignant plus que la partie codage d'un modèle objet obtenu par AOO et COO.

Typage et classification

Dans l'approche Objet, les systèmes sont uniquement constitués d'entités (appelées objet) ayant chacune des caractéristiques qui sont définies par leur type. Il existe deux grandes théories des types. Celle, initiale, de Liskov et celle, plus actuelle, de Cook. Dans chacune, deux concepts sont définis : celle du typage et celle de classification.

Le typage selon Liskov

Les types, dans la théorie des types de Liskov, et dont une définition sémantique a été donnée par Cardelli, sont dits types de premier ordre. Un type, en programmation orienté objet, définit de façon syntaxique et sémantique les aspects visibles que présenteront les objets (les valeurs) du type ; ces propriétés sont tout ce que le programmeur et les autres objets auront besoin de connaître et connaîtront de l'objet. La question de sa représentation en mémoire ne sera pas posée et il sera possible de la changer à tout moment sans impact sur son utilisation. Ces aspects visibles forment l'interface de l'objet. Dans le typage du premier ordre, les classes fournissent l'implémentation (la façon dont les propriétés sont réellement représentées) des caractéristiques du ou des types qu'elles représentent ; les propriétés seront soient représentées sous forme d'emplacement mémoire (champs de donnée) que l'on appelle couramment attribut, soit sous forme de calculs (opérations) que l'on appelle couramment méthode. Donc, si un type définit l'interface de l'objet, la classe lui fournit une implémentation. On a une dualité type/classe. À ce titre, la classe nombre complexe est le moule par lequel sont construit tous les objets de nombres complexes. Un objet est dit alors instance de sa classe. Par cette démarche, l'approche Objet introduit deux types d'héritage :

L'héritage est la faculté d'une sous-classe ou d'un sous-type d'hériter des propriétés de son parent et de les raffiner. Le sous-typage est donc le processus par lequel on restreint l'espace des valeurs du type parent, et la sous-classification est le processus par lequel on récupère et on spécialise l'implémentation.

Le typage selon Cook

Toutefois, la théorie des types de Liskov se heurte au problème du sous-typage des types récursifs (les types avec au moins une opération qui accepte un objet de même type). La théorie des types de Cook (la théorie F-Bound) permet de résoudre ce problème en redéfinissant ce qu'est un type et ce qu'est une classe. Elle définit ce que l'on appelle le typage du second-ordre. Dans cette approche, les concepts de classe et de type ne sont plus duals mais imbriqués. Une classe ne définit plus l'implémentation d'un ou de plusieurs types. Si le type définit toujours l'interface des objets, la classe définit l'implémentation d'une famille polymorphique finie et liée de types. Le type est devenu un élement d'une classe. Dans cette approche, l'accent n'est plus mis sur le sous-typage comme dans celle de Liskov, mais sur la sous-classification ; un héritage va décrire l'arborescence entre classes (et donc implicitement entre types). La sous-classification permet de restreindre l'espace des types. Ainsi, par exemple, le type Entier fait parti de la classe des nombres, mais aussi de celle des réels et des entiers, toutes deux sous-classes de nombres (la classe des entiers est sous-classe des réels aussi) :

classe_nombre [ T -> classe_nombre [T] ] = { plus: T x T -> T }
classe_entier [ T -> classe_entier [T] ] = { plus: T x T -> T, moins: T x T -> T }
classe_entier <: classe_nombre
entier = classe_entier [ entier -> classe_entier [entier] ] 
 = { plus: entier x entier -> entier, moins: entier x entier -> entier }
 < classe_nombre [ entier -> classe_nombre [entier] ]

(Ici entier est le point fixe de la classe classe_entier et membre de la classe classe_nombre. classe_entier est sous-classe de classe_nombre.)

Le typage du premier ordre inclut des langages comme Java et C++. Celui du second ordre inclut des langages comme Smalltalk et Eiffel.

Le principe d'encapsulation

Le paradigme objet, quelque soit l'approche adoptée (le typage selon Liskov ou selon Cook), découple l' interface (ce qu'on voit d'un objet) de l'implémentation (la façon dont on va pratiquement représenter les choses par un savant mélange de mémoire et de calculs, comme dans nos nombres complexes du premier exemple : le programmeur peut les additionner ou les multiplier sans se soucier de leur représentation interne). C'est le principe d'encapsulation : l'implémentation est cachée de l'extérieur par l'interface (définition syntaxique et sémantique des propriétées). Les objets n'utilisent des autres objets que les propriétés définies par leur interface, quelque soit leur représentation interne. Cette encapsulation existait de façon embryonnaire dans des langages comme le PL/I (où par exemple le programmeur pouvait ignorer à son niveau si le nom qu'il utilisait dans une expression était celui d'une variable ou d'une fonction sans arguments (par exemple TIME), ou en APL qui de façon plus radicale permet de définir alternativement un même nom comme celui d'une variable ou d'une fonction selon l'empilement des contextes (« localisation des noms ») à l'exécution.

L'objet

Un objet est caractérisé, dans un système logiciel, par une identité et des propriétés. Les propriétés de l'objet sont définies par son type. Ceux-ci peuvent-être découpées en deux parties distincites: l'état et le comportement.

On distingue deux grandes familles de langage objet dans la déclaration du type des objets : les langages à typage dynamique et ceux à typage statique.

Dans la première famille, nous avons des langages comme C++, Java et Eiffel. Dans la seconde famille, nous avons des langages comme Smalltalk, CLOS et Python.

Autres aspects

Les langages à objet peuvent être classés selon qu'ils ont les propriétés suivantes :

Modélisation objet

La modélisation objet consiste à créer un modèle informatique du système de l'utilisateur (un système informatique). Ce modèle peut rassembler aussi bien des élements du monde réel que des concepts ou des idées propres au métier ou au domaine duquel fera partie le système. La modélisation Objet consiste à définir, à qualifier dans un premier temps ces élements sous forme de types, donc indépendemment de l'implémentation. C'est ce que l'on appelle l'analyse orientée objet ou OOA (Object-Oriented Analysis).

Puis, on propose une ou des solutions techniques pour représenter les éléments définis dans le système informatique. C'est ce que l'on appelle la conception orientée objet ou OOD (Object-Oriented Design). Une fois un modèle de conception établi, il est possible au développeur de leur donner corps dans un langage de programmation. C'est ce que l'on appelle la programmation orientée objet ou OOP (Object-Oriented Programming). À un modèle d'analyse peuvent correspondre plusieurs modèles de conception.

Pour écrire ces différents modèles, différents langages et méthodes ont été mis au point, dont OMT de Rumbaugh, BOOCH'93 de Booch et OOSE de Jacobson. Toutefois, ces méthodes ne permettaient de modéliser que certains types d'applications et se trouvaient limitées dans d'autres contextes. La méthode OMT prévalait sur l'ensemble des autres méthodes dans la première partie de la décennie 1990.

À partir de 1994, Rumbaugh, Booch et Jacobson ont décidé de s'unir dans l'élaboration d'une nouvelle méthode, suffisamment générique, pour pouvoir s'appliquer à quasiment tous les contextes applicatifs. Ils ont commencé d'abord par définir un langage de modélisation fortement inspiré de celles des méthodes des trois auteurs : UML (Unified Modeling Language). Une fois celui-ci pris en charge par l'OMG (Object Management Group), un organisme destiné à standardiser des technologies objet, comme CORBA (Common Object Request Broker), un intergiciel objet réparti, Rumbaugh, Booch et Jacobson se sont attaqués à la méthode proprement dite: USDP (Unified Software Development Process). Cette méthode définit un cadre générique de développement objet avec UML comme langage de modélisation. USDP (généralement raccourci en UP) est une méthode itérative et incrémentale, centrée sur l'architecture et guidée par les cas d'utilisation et la réduction des risques. C'est aux concepteurs de s'attribuer cette méthode en l'instanciant à leur métier et à leur domaine.

Néanmoins pour un certain nombre de concepteurs objet, dont Bertrand Meyer, l'inventeur du langage orienté objet Eiffel, guider une modélisation objet par des cas d'utilisations est une erreur de méthode qui n'a rien d'objet et qui est plus proche d'une méthode fonctionnelle. Pour eux, les cas d'utilisations sont relégués à des utilisations plutôt annexes comme la validation d'un modèle par exemple.

Sujet lié

Bibliographie




This site support the Wikimedia Foundation. This Article originally from Wikipedia. All text is available under the terms of the GNU Free Documentation License Page HistoryOriginal ArticleWikipedia