OpenScheme : Programmation objet

Par :

Guilhem de Wailly (gdw@erian-concept.com)



et :

Fernand Boéri (boeri@unice.fr)



Résumé

Depuis plusieurs mois, nous décrivons dans ces colonnes le langage Scheme. Cette description était générale et s'appuyait sur le standard de fait appelé Revised4 Report On The Algoritmic Language Scheme.

Nous avons présenté les éléments importants du langage et tenté d'illustrer cela par des exemples, comme un moteur base de donnée reposant sur les tables de hachage ou un simulateur de circuits électroniques logiques.

Cette nouvelle série d'article présente plus spécifiquement l'environnement de programmation OpenScheme.

Cet article sert d'introduction à la programmation orientée objet en présentant succinctement la méthode d'analyse OMT. Il n'est pas question ici de développer la méthode, mais seulement de présenter les bases sur les quelles nous nous appuierons dans des prochains articles.

L'environnement OpenScheme est disponible sur le CDROM de Linux Magazine.

Introduction

L'environnement de programmation OpenScheme (OSM) possède un puissant moteur orienté objet. Ce moteur est notamment utilisé pour réaliser la bibliothèque graphique de haut niveau.

Dans cet article, nous présentons très succinctement une méthode d'analyse pour la programmation orientée objet (POO), la méthode OMT. L'ouvrage de référence est donné en annexe.

Cette présentation va servir d'introduction aux concepts utilisée en POO. Dans un prochain article, nous introduirons la POO en OSM.

Nous rappelons qu'OSM est disponible sur le WEB (référence en annexe) et sur le CDROM de Linux Magazine.

Programmation Orientée Objet

Introduction

La programmation orientée objet permet de concevoir une application sous la forme d'un ensemble d'objets reliés entre eux par des relations : Lorsque que l'on programme avec cette méthode, on se pose plus souvent la question `` qu'est-ce que je manipule ? '', que `` qu'est-ce que je fait ? ''.

Le programme orienté objet est pensé en terme d'objets abstraits inter opérant entre eux alors que la programmation traditionnelle pense une application en termes de fonctionnalités.

L'une des caractéristiques de cette méthode permet de concevoir de nouveaux objets à partir d'objets existants. Ainsi, il est possible de spécialiser un objet pour des besoins spécifiques. On peut donc réutiliser les objets dans plusieurs applications. La réutilisation du code fut un argument souvent exagéré pour venter les avantages des langages à objets.

Le programme est donc composé d'un assemblage d'objets dont on récupère les propriétés pour les spécialiser à la nouvelle application.

Les interfaces graphiques se prêtent bien à une conception orientées objets car les objets ne sont pas seulement abstraits mais possèdent une représentation graphique sous la forme d'une fenêtre ou d'un élément graphique.

Langages

L'un des premiers langages orientés objet est SmallTalk 72 qui, dans ses premières versions étaient écrites en … Lisp !

Un autre langage orienté objet est le C++, basé sur le langage C.

Ces deux langages objets reposent sur deux technologies différentes. SmallTalk est un langage orienté objet dynamique. Cela signifie que certaines résolutions sont effectuées au moment ou l'application est exécutée. Le langage C++ est quant à lui statique dans la mesure ou toutes les résolutions sont prises au moment de la compilation. Les deux technologies ont leurs avantages et leurs inconvénients.

D'autres langages objets ont vu le jour, comme ObjectiveC, utilisé dans le système Next, VisualBasic, Java. A propos de ce dernier, certains disent que Java à un ancêtre, et que c'est Lisp.

Le langage Scheme n'est pas, à la base, un langage orienté objet. Mais ses possibilités d'extensions, principalement les à l'aide des macros, ont permis de définir assez facilement des moteurs objets. On peut citer le moteur MEROON de C.Queinnec ou TINYCLOS de Gregor.

Pratiquement tous les environnements Scheme proposent un système objet. OpenScheme propose l'environnement OO sous la forme d'un plugin.

Concept

Dans un système orienté objets, un objet comprend à la fois une structure de donnée et un comportement.

Un système est dit orienté objet lorsqu'il possède quatre caractéristiques que nous allons examiner : identité, classification, polymorphisme et héritage.

Identité

Un objet est unique et peut être identifié de manière unique dans le système. Cela se rapproche du monde réel ou chaque objet est unique : Le Linux Magazine que vous tenez entre vos mains est unique et ne peut pas être confondu avec un autre.

Classification

Les objets partageant la même structure de donnée et le même comportement sont regroupés en classes. La classe décrit les propriétés de l'objet dans une application donnée.

La structure de donnée d'un objet constitue ses attributs et son comportement ses opérations.

Un objet particulier est dit instance de sa classe. Dans un ordinateur graphique, on peut avoir la classe Fenêtre, et plusieurs instances de cette classe, chacune représentée par un rectangle sur l'écran.

Chaque instance d'une classe possède ses propres valeurs mais elle partage la structure de donnée et son comportement avec les autres instances de sa classe.

Dans certains systèmes, les classes elles-mêmes sont des objets. On dit que le système utilise un Meta Object Protocol (MOP). C'est le cas de MEROONET, de CLOS (Common Lisp Object System) et de OO.

Polymorphisme

Dans un système orienté objet polymorphe, une même opération se comporte différemment sur différentes classes. Par exemple, l'opération afficher dans un système fenêtré se comporte différemment sur les objets de la classe Bouton et sur la classe Ascenseur.

Pour une classe donnée, une opération est réalisée par une méthode.

Une opération est donc implémentée dans un système par ensemble de méthodes, chacune s'appliquant à une classe particulière. L'opération est dite polymorphe car elle est applicable à plusieurs classe d'objets.

Héritage

Lorsqu'une classe hérite d'une autre classe, elle possède les attributs et le comportement de la classe ancêtre en plus de ceux qu'elle définit. La structure des classes est donc hiérarchique.

La conception orientée objet encourage à définir des classes générales et abstraites, puis à raffiner ces propriétés dans les classes filles, de manière à les adapter à l'application. La réutilisation de code est ainsi possible.

Terminologie

Abstraction

L'abstraction consiste à se préoccuper en priorité des caractéristiques essentielles d'un objet et à en ignorer les détails. Cela permet de concentrer l'effort d'analyse et de développement sur l'architecture de l'application avant de penser en terme de réalisation.

L'héritage et le polymorphisme sont de puissants outils d'abstraction permettant une réutilisation importante du code.

Les méthodes d'analyse abstraite comme OMT permettent de retarder les détails de programmation au plus tard en proposant une manière de décrire l'application indépendante de tout langage.

Encapsulation

L'encapsulation consiste à séparer les aspects externes d'un objet des aspects internes. Ceci permet de limiter l'interface (ce qui est visible et accessible) de l'objet et de protéger les détails de réalisation `` à l'intérieur de l'objet ''.

Ainsi, il est possible de modifier la manière avec laquelle est réalisé l'objet sans altérer son interface. De ce fait, les programmes utilisant cette interface n'ont pas à être modifiés.

Structure de donnée et comportement

Le système orienté objet est chargé d'invoquer la bonne procédure en fonction de la méthode appelée et de l'objet à la quelle elle s'applique. Par exemple, un programme non orienté objet doit, pour afficher le contenu d'une fenêtre, invoquer la procédure dessiner adaptée au type de la figure, comme dessiner_polygone, dessiner_cercle,...

Dans un programme orienté objet, la méthode dessiner est invoquée pour chaque figure, et le système est chargé d'appeler la bonne procédure. Ainsi, il n'est pas besoin de modifier le code d'affichage d'une fenêtre chaque fois que l'on ajoute une nouvelle figure : il suffit d'appeler la méthode dessiner. Le code de la procédure d'affichage de la fenêtre est devenu indépendant des figures et du type des figures à afficher.

Partage

Les langages orientés objet permettent de partager simplement des structures de données. L'héritage autorise la spécialisation d'une structure de donnée, à partir d'une structure plus générale.

Le partage du code est aussi possible en réutilisant les méthodes définies pour des objets plus primitifs.

Le système orienté objet permet aussi d'utiliser du code non encore écrit. C'est par exemple le cas avec l'affichage d'une fenêtre utilisant la méthode dessiner pour des figures, sans savoir à quelles figures elle s'applique. Lorsque qu'une nouvelle figure est définie, la méthode dessiner y sera appliquée.

Synergie

Un système orienté objet repose sur les principes d'identité, de classification, de polymorphisme et d'héritage.

L'usage conjoint de ces principes amène l'équipe de développement à une analyse poussée des applications, en raisonnant en terme de réutilisation et d'abstraction.

Les applications orientées objet sont, en général, mieux développées dans la mesure ou un plus grand soin a été porté à l'analyse préliminaire.

Outils d'analyse

Nous proposons maintenant un exemple simple d'analyse objet d'une application. Elle repose sur la méthode OMT dont la référence est donnée en annexe.

L'analyse orientée objet repose principalement sur l'analyse des classes de l'application et les relations qui les lient entre elles.

Une classe est composée d'attributs qui constituent la structure de donnée des instances de la classe. Elle est représentée graphiquement par :

Figure 1: Classe

Il est possible d'indiquer des contraintes sur les attributs, entre accolades. Par exemple, on pourrait écrire {attribut >= 0}. La contrainte se place soit à l'extérieur du rectangle de la classe, soit à l'intérieur.

Deux types de relation peuvent lier deux classes : une relation hiérarchique et une relation associative.

La relation hiérarchique influence la structure de la classe, c'est à dire les attributs qui la composent. Lorsqu'une classe hérite d'une autre classe, elle possède les attributs de la classe ancêtre en plus de ceux qu'elle définit. La relation hiérarchique est représentée par :

Figure 2 : Héritage

La relation associative influence les dépendances entre les instances des classes. Par exemple, dans un logiciel de comptabilité, une facture correspond toujours à un client. Ceci se traduit par une relation entre les deux classes.

Une relation associative est représentée par :

Figure 3 : relation entre classes.

Les relations entre classes jouent un rôle très important dans l'organisation des données. On retrouve ce concept dans les gestionnaires de base de données.

On distingue donc plusieurs catégories de relations, chaque catégorie étant représentée par :

Figure 4 : multiplicité des relations

Lorsque l'on analyse une application, il est important de connaître les relations entre les classes. Pour cela, on se pose la question `` pour un objet de la première classe, combien correspondent d'objets de la seconde classe ? ''. La réponse à cette question détermine la multiplicité de chaque relation. Par exemple `` à un objet de la classe FACTURE, combien correspondent d'objets de la classe CLIENT ? ''. Dans ce cas, la réponse est Un et un seul. Par contre la réponse à `` à un objet de la classe FACTURE, combien correspondent d'objets de la classe BON DE LIVRAISON ? ''. Ici, la réponse est Zéro ou un.

Exemple

Cet exemple montre comment modéliser des figures géométriques destinées à être affichées. Ici, nous nous préoccuperons seulement des caractéristiques des figures, sans tenir compte des contraintes imposées par l'affichage proprement dit.

Nous proposons le graphe de classe suivant :

Figure 5 : Relation entre classes

Ce graphe montre les relations entre les classes de l'application. Les classes FIGURE et COULEUR sont des classes ancêtres dans la mesure ou aucune autre classe n'en hérite.

Les classes RECTANGLE et CERCLE héritent de la classe FIGURE. Elles en possèdent donc les attributs et les opérations.

Il en va de même pour la classe CARRE qui hérite de RECTANGLE. Elle possède aussi les attributs de la classe RECTANGLE et de la classe FIGURE.

Les classes FIGURE et COULEUR sont en relation dont la multiplicité est 2 : cela signifie qu'à toute instance de la classe FIGURE (ou d'une de ses filles) correspond exactement deux instances de la classe COULEUR.

Il reste maintenant à définir les classes une par une.

La classe FIGURE est définie comme suit :

Figure 6 : Classe FIGURE.

Toutes les classes qui vont hériter de cette classe possèderont les attributs Couleur_trait et Couleur_fond.

L'opération dessiner est une fonction qui affichera par exemple un point d'interrogation pour indiquer qu'une figure, sans autre précision, ne sait pas se dessiner.

La première figure est le RECTANGLE dont la class est définie par :

Figure 7 : Classe RECTANGLE

La classe RECTANGLE possède deux attributs que sont la largeur et la hauteur. Elle redéfinit aussi l'opération dessiner pour l'adapter aux contraintes spécifiques du dessin d'un rectangle. On dit qu'elle surcharge l'opération dessiner.

Définissions maintenant la classe CARRE :

Figure 8 : Classe CARRE.

La classe CARRE hérite de la classe RECTANGLE. Elle en possède donc les attributs et les opérations. Mais elle ajoute une contrainte sur la largeur et la hauteur qui doivent être identiques. L'opération dessiner définie pour la classe RECTANGLE sera réutilisée telle quelle pour la classe CARRE, sans qu'il y ait besoin de la surcharger.

Il en va de même pour les classes ELLIPSE et CERCLE.

La méthode OMT permet d'aller beaucoup plus loin dans la modélisation de l'application. Cependant, ces bases suffiront dans les prochains articles.

Les auteurs

Guilhem de Wailly, directeur de la société Erian Concept : support, formations, configurations, administration, développements Linux. Environnement OpenScheme.

http://www.erian-concept.com



Fernand Boéri, Professeur à l'Université de Nice - Sophia-Antipolis, membre de l'unité SPORTS du laboratoire I3S, spécialiste en modélisation, évaluation de performances et architectures parallèles.

http://www.i3s.unice.fr

Références

Programmation orientée objet

 OMT: 1-Modélisation et conception orientées objet
James Bumbaugh et al.
Masson / Prentice Hall

Scheme

 Structure et Interprétation des programmes informatiques
H. Abelson, GJ. Sussman
InterEdition

 The Scheme Programming Languages - Ansi Scheme
R. Kent Dybvig
Prentice Hall

 Les langages Lisps - Christian Queinnec
InterEdition

 Programmer avec Scheme - J. Chazarin
Thomson Publishing

 Revised4 Report on the Algorithmic Language Scheme
W. Clinger, J. Rees
ftp://ftp.nj.nec.com/pub/kelsey

Environnements Scheme

 Scm - A. Jaffer
http://www-swiss.ai.mit.edu/~jaffer
La référence des interprètes Scheme. Très petit, rapide, pour beaucoup de plates-formes, extensible.

 PCScheme - Texas Instrument
ftp://cui.unige.ch/public/pcs/pcscheme.exe
Un très bon environnement de programmation Scheme pour DOS, avec éditeur intégré.

 DrScheme - Rice University
http://www.cs.rice.edu/CS/PLT/
Environnement Scheme libre très avancé.

 ChezScheme - Cadence, Inc
http://www.scheme.com/
Environnement Scheme très performant.

 Inlab Scheme - Inlab Software GmbH
http://www.munich.net/inlab/scheme/
Environnement commercial

 EdScheme, 3Dscheme - Scheme, Inc
http://www.schemers.com/
Environnement de programmation Scheme pour Windows.

 OpenScheme - Erian Concept
http://www.open-scheme.com
Environnement professionnel de programmation Scheme comprenant un interprète, un compilateur et un débogueur symbolique.
Existe en version libre et commerciale, pour Linux, FreeBSD, Solaris, Windows et BeOS, sur plateformes Intel.