Re: definition de type

トップ ページ

このメッセージに返信
著者: Yves Martin
日付:  
To: guilde
題目: Re: definition de type
En réponse à Miguel Moquillon <miguel.moquillon@???>:

> On Sun, Jun 23, 2002 at 11:08:53AM +0200, Torgue Philippe wrote:
> > Bonjour,
> >
> > Voilà, je veux construire une fonction qui retourne
> > un type énumérée.
> > En C on peut facilement construire le type énumérée, le nommer, et
> > contraindre une fonction à retourner des valeurs de ce type.
> >
> > Cependant, je ne retrouve pas le type énumérée en Java.
> > [...]
>
> Donc, pour un type enumere, elle peut etre definie par une classe qui
> n'engendre que des instances ayant des valeurs particulieres.
> Maintenant,
> est-ce exact du point de vue objet ... je ne le crois pas car en
> Objet,
> un objet est une entite qui evolue au gres des interactions. Un objet
> est caracterise par un etat et un ensemble de comportements. L'etat
> est
> defini par l'ensemble des resultats des interactions issues sur
> l'objet
> et le comportement defini l'ensemble des interactions qui peuvent etre
> appliquer a l'objet. En fait, le terme de comportement est un abus de
> langage issu des implementations du paradigme objet dans des langages
> de
> programmation. Le terme exact est /propriete/. Donc, si un objet ne
> possede qu'une valuer (son etat ne prend qu'une valeur), il y a un pb
> de modelisation objet quelque part.


Le problème d'utiliser un 'entier' ne contraint en rien l'utilisateur
à respecter des valeurs définies à moins de faire un coûteux 'check'
des valeurs possibles avec retour d'exception en entrée de la méthode
s'il s'agit d'argument.

Bien que l'objet puisse avoir des attributs et des états,
il existe le pattern de "singleton", objet unique du système.
On peut donc définir une class par type énuméré, et un singleton par
instance possible de ce type

public class Enumeration {

     public static final Enumeration VALUE1 = new Enumeration( 1 );
     public static final Enumeration VALUE1 = new Enumeration( 2 );


     private int enumeratedValue;


     private Enumeration( int value ) {
         enumeratedValue = value;
     }


     public int getValue() {
         return enumeratedValue;
     }
  }


La valeur du type énuméré est représenté par un entier mais on peut
aussi utiliser une chaîne, ou les deux...

   Pourquoi un constructeur privé ? pour interdire l'instanciation de
   la classe avec des valeurs non autorisées.
   L'accès aux instances du type énuméré se fait avec le statement
      Enumation.VALUE1, Enumeration.VALUE2


   On peut même faire une comparaison de pointeur
      if ( enumValue == Enumeration.VALUE1 ) ...


Attention: cela n'est valable que dans une seule JVM, les valeurs
énumérées transmises par serialization entre 2 JVM doivent être
converties par le mécanisme de 'readResolve' mais cela complique
mon explication donc les personnes intéressées peuvent me contacter
en privé.

   Inconvénient: l'obligation de faire des 'if then elsif then else'
     à la place du pratique 'switch'


Cependant la méthode getInt permet d'utiliser le switch
mais alors on utilise les valeurs entières 'en dur'

   switch( enum.getInt() ) {
      case 1:
      case 2:
      default:
   }



public class Enumeration {

     public static int INT_VALUE1 = 1;
     public static int INT_VALUE2 = 2;


     public static final Enumeration VALUE1 = new Enumeration( INT_VALUE1 );
     public static final Enumeration VALUE1 = new Enumeration( INT_VALUE2 );


     private int enumeratedValue;


     private Enumeration( int value ) {
         enumeratedValue = value;
     }


     public int getValue() {
         return enumeratedValue;
     }
  }


Ainsi les prototypes de méthodes peuvent prendre en argument
une instance de la classe 'Enumeration' ou retourner une instance de
Enumeration.
et ensuite on peut travailler avec

   switch( enum.getInt() ) {
      case Enumeration.INT_VALUE1:
      case Enumeration.INT_VALUE2:
      default:
   }


Cette double définition entiers + instances singleton évite
les problèmes de modification de numérotation dans le type énuméré
et de maintenance du code.

  On peut compléter avec une méthode statique:
     Enumeration getEnumeration( int value ) 
  qui retourne l'instance singleton en fonction de la valeur entière
  avec une table de hash statique HashMap/Hashtable qui contient toutes
  les instances singleton de l'énumération, table alimentée par le 
  constructeur de Enumeration.


Comme vous pouvez le constater, j'ai pas mal planché sur le sujet.
Notre solution (c'est pour mon boulot) n'est pas parfaite mais elle
couvre pas mal de besoins en forçant l'usage des seules valeurs possibles.

--
Yves Martin