Vous êtes sur la page 1sur 5

PD

PD

F-

XC

h a n g e Vi e

F-

XC

h a n g e Vi e

er

er

O W

bu

to

lic

lic

to

bu

N
.c

O W
w
.d o
c u -tr a c k

.d o

c u -tr a c k

.c

6
Objets et structures de donnes

Si nous voulons que nos variables soient prives, cest pour une bonne raison : nous voulons que personne dautre en dpende. Nous voulons garder la libert de modifier leur type ou leur implmentation sur un coup de tte ou une envie soudaine. Dans ce cas, pourquoi tant de programmeurs ajoutent automatiquement des accesseurs (mthodes get et set) leurs objets, exposant ainsi leurs variables prives comme si elles taient publiques ?

w
w

w
w

PD

PD

F-

XC

h a n g e Vi e

F-

XC

h a n g e Vi e

er

er

O W

to

lic

lic

to

104
o
.c

Coder proprement
w
w

bu

bu

N
.d o
c u -tr a c k

O W

.d o

c u -tr a c k

.c

Abstraction de donnes
Examinons la diffrence entre le Listing 6.1 et le Listing 6.2. Ils reprsentent tous deux les donnes dun point dans le plan cartsien, mais un seul expose son implmentation.
Listing 6.1 : Classe Point concrte
public class Point { public double x; public double y; }

Listing 6.2 : Classe Point abstraite


public interface Point { double getX(); double getY(); void setCartesian(double x, double y); double getR(); double getTheta(); void setPolar(double r, double theta); }

Le Listing 6.2 a ceci dintressant quil nexiste aucun moyen de savoir si limplmentation est fonde sur des coordonnes rectangulaires ou polaires, voire ni lune ni lautre. Malgr tout, linterface reprsente incontestablement une structure de donnes. Toutefois, elle ne reprsente pas uniquement une structure de donnes. Les mthodes imposent une politique daccs. Nous pouvons lire indpendamment chaque coordonne, mais nous devons les fixer ensemble par une opration atomique. Le Listing 6.1, quant lui, est trs clairement mis en uvre laide de coordonnes rectangulaires et nous oblige les manipuler de manire indpendante. Il expose limplmentation. Bien videmment, il continuerait dexposer limplmentation mme si les variables taient prives et si nous utilisions des accesseurs pour chacune. Pour masquer limplmentation, il ne suffit pas de placer une couche de fonctions devant les variables. Ce problme concerne les abstractions ! Une classe ne peut pas se contenter de prsenter ses variables au travers daccesseurs. la place, elle doit exposer des interfaces abstraites qui permettent ses utilisateurs de manipuler lessence des donnes, sans avoir en connatre limplmentation. Examinons le Listing 6.3 et le Listing 6.4. Le premier emploie des termes concrets pour indiquer le niveau de carburant dans un vhicule, tandis que le second utilise pour cela labstraction des pourcentages. Dans la classe concrte, nous pouvons tre pratiquement certains quil sagit de mthodes daccs aux variables. Dans le cas abstrait, nous navons aucun indice sur la forme des donnes.

w
w

PD

PD

F-

XC

h a n g e Vi e

F-

XC

h a n g e Vi e

er

er

O W

to

lic

lic

to

Chapitre 6
o
.c

Objets et structures de donnes

105
w
w

bu

bu

N
.d o
c u -tr a c k

O W

.d o

c u -tr a c k

.c

Listing 6.3 : Classe Vehicle concrte


public interface Vehicle { double getFuelTankCapacityInGallons(); double getGallonsOfGasoline(); }

Listing 6.4 : Classe Vehicle abstraite


public interface Vehicle { double getPercentFuelRemaining(); }

De ces deux approches, il est prfrable dopter pour la seconde. Nous ne souhaitons pas exposer les dtails de nos donnes. Nous voulons la place exprimer nos donnes en termes abstraits. Cela ne passe pas simplement par lemploi dinterfaces et/ou daccesseurs. Il faut une rflexion srieuse sur la meilleure manire de reprsenter les donnes contenues dans un objet. La pire solution consiste ajouter sans discernement des mthodes daccs.

Antisymtrie donnes/objet
Les deux exemples prcdents rvlent la diffrence entre les objets et les structures de donnes. Les objets cachent leurs donnes derrire des abstractions et fournissent des fonctions qui manipulent ces donnes. Les structures de donnes exposent directement leurs donnes et ne fournissent aucune fonction significative. Ces deux concepts sont virtuellement opposs. La diffrence peut sembler vidente, mais ses implications sont profondes. Prenons lexemple des formes procdurales du Listing 6.5. La classe Geometry opre sur les trois classes de formes, qui sont de simples structures de donnes sans aucun comportement. Tout le comportement est dfini dans la classe Geometry.
Listing 6.5 : Formes procdurales
public class Square { public Point topLeft; public double side; } public class Rectangle { public Point topLeft; public double height; public double width; } public class Circle { public Point center; public double radius; }

w
w

PD

PD

F-

XC

h a n g e Vi e

F-

XC

h a n g e Vi e

er

er

O W

to

lic

lic

to

106
o
.c

Coder proprement
w
w

bu

bu

N
.d o
c u -tr a c k

O W

.d o

c u -tr a c k

.c

public class Geometry { public final double PI = 3.141592653589793; public double area(Object shape) throws NoSuchShapeException { if (shape instanceof Square) { Square s = (Square)shape; return s.side * s.side; } else if (shape instanceof Rectangle) { Rectangle r = (Rectangle)shape; return r.height * r.width; } else if (shape instanceof Circle) { Circle c = (Circle)shape; return PI * c.radius * c.radius; } throw new NoSuchShapeException(); } }

Les programmeurs orients objet pourraient faire la grimace devant ce code et critiquer son approche procdurale ils auraient raison. Cependant, le mpris nest pas justifi. Voyons ce qui se passe si une fonction perimeter() est ajoute Geometry. Les classes de formes ne sont pas affectes ! Aucune autre classe qui dpend des formes nest affecte ! En revanche, si nous ajoutons une nouvelle forme, nous devons modifier toutes les fonctions de Geometry pour en tenir compte. Relisez nouveau ces derniers points. Vous pouvez remarquer que ces deux critres sont diamtralement opposs. Examinons prsent le cas de la solution oriente objet du Listing 6.6, o la mthode area() est polymorphe. Aucune classe Geometry nest requise. Si nous ajoutons une nouvelle forme, aucune des fonctions existantes nest affecte mais, si nous ajoutons une nouvelle fonction, toutes les formes doivent tre modifies1 !
Listing 6.6 : Formes polymorphes
public class Square implements Shape { private Point topLeft; private double side; public double area() { return side*side; } }

1. Il existe des solutions pour contourner cet inconvnient et les concepteurs orients objet expriments les connaissent parfaitement : le motif VISITEUR ou la double distribution, par exemple. Mais les cots intrinsques ces techniques ne sont pas ngligeables et elles renvoient gnralement la structure vers une approche procdurale.

w
w

PD

PD

F-

XC

h a n g e Vi e

F-

XC

h a n g e Vi e

er

er

O W

to

lic

lic

to

Chapitre 6
o
.c

Objets et structures de donnes

107
w
w

bu

bu

N
.d o
c u -tr a c k

O W

.d o

c u -tr a c k

.c

public class Rectangle implements Shape { private Point topLeft; private double height; private double width; public double area() { return height * width; } } public class Circle implements Shape { private Point center; private double radius; public final double PI = 3.141592653589793; public double area() { return PI * radius * radius; } }

Nous constatons nouveau la nature complmentaire de ces deux dfinitions ; elles sont virtuellement opposes ! Cela rvle la dichotomie fondamentale entre les objets et les structures de donnes :
Un code procdural (un code qui utilise des structures de donnes) facilite lajout de nouvelles fonctions sans modifier les structures de donnes existantes. Un code orient objet facilite lajout de nouvelles classes sans modifier les fonctions existantes.

Linverse est galement vrai :


Un code procdural complexifie lajout de nouvelles structures de donnes car toutes les fonctions doivent tre modifies. Un code orient objet complexifie lajout de nouvelles fonctions car toutes les classes doivent tre modifies.

Par consquent, ce qui est difficile pour lorient objet est facile pour le procdural, tandis que ce qui est difficile pour le procdural est facile pour lorient objet ! Dans un systme complexe, nous aurons parfois ajouter de nouveaux types de donnes la place de nouvelles fonctions. Dans ce cas, lapproche oriente objet est approprie. En revanche, lorsque nous aurons ajouter de nouvelles fonctions, non des types de donnes, un code procdural et des structures de donnes seront mieux adapts. Les programmeurs expriments savent trs bien que lide du tout objet est un mythe. Parfois, nous voulons rellement de simples structures de donnes avec des procdures qui les manipulent.

w
w

Vous aimerez peut-être aussi