Type-safe enumération

Type-safe enumération

Aujourd’hui, je vais vous parler du design pattern Type-safe énumération et de son implémentation en Java 1.4.

Ceux qui travaillent en Java5 connaissent bien et utilisent (enfin, je l’espère pour eux) les énumérations, et bien, avec un peu plus d’effort, ce design pattern est implémentable aussi en Java 1.4, je vais ici en donner un exemple tirer de l’implémentation de Doug Lea, qui est celle qui a donné naissance à l’implémentation de référence de Java 5.

Type-safe énumération. Classe qui permet de définir une énumération d’éléments, ne contenant aucun constructeur public, elles construit à l’instantiation la liste de ses éléments. Les éléments de l’énumération sont immuable (immutable), on ne peut les modifier. Pour plus de facilité, nous feront en sorte que les éléments soit directement comparable et sérialisable (conseillé en J2EE).

Le grand intérêt d’utiliser les énumération est que cela permet de clarifier grandement le code et de garantir l’utilisation des éléments comme ils ne peuvent être modifiés depuis l’extérieure de la classe.

Exemple en Java 1.4

/**
 * @author Loïc MATHIEU
 */
public class MarquesVoitures implements Serializable, Comparable
{

    //Le code est transient car les objet sont créé à l'instantiation.
    private transient String mCode;	

    //Ces deux compteurs vont automatiquement s'incrémenter grâces aux instantiations ci-dessous
	private static int sNextOrdinal;
	private final int mOrdinal = sNextOrdinal++;

	private static List sPrivateValues = new ArrayList();

	//Utilisé pour pouvoir récuperer un élément de l'énumération depuis son code
	private static Map sIndexedValues = new HashMap();

	//Instantiations des éléments de l'énumération
	public static final MarquesVoitures RENAULT = new MarquesVoitures("renault");
	public static final MarquesVoitures PEUGEOT = new MarquesVoitures("peugeot");
	public static final MarquesVoitures CITROEN = new MarquesVoitures("citroen");
	public static final MarquesVoitures LADA = new MarquesVoitures("lada ");

	private static final MarquesVoitures[] PRIVATE_VALUES =
	    	(MarquesVoitures[]) sPrivateValues.toArray(new MarquesVoitures[0]);

	public static final List VALUES = Collections.unmodifiableList(sPrivateValues);

	private MarquesVoitures(String aCode) {
		mCode = aCode;

		sPrivateValues.add(this);
		sIndexedValues.put(aCode, this);
	}

	public int compareTo(Object aObject) {
		return mOrdinal - ((MarquesVoitures) aObject).mOrdinal;
	}

	/**
	 * Methode appelé lors du process de serilization/deserialization
	 */
	private Object readResolve() throws ObjectStreamException {
		return create(mOrdinal);
	}

	public String getCode() {
		return mCode;
	}

	private static MarquesVoitures create(int mOrdinal) {
		return PRIVATE_VALUES[mOrdinal];
	}

	/**
	 * Permet de récupérer un élément de l'énumération depuis son code,
	 * donc de récupére l'objet depuis sa String identifiant
	 */
	public static MarquesVoitures getMarquevoiture(String aCode) {
	    return (MarquesVoitures) sIndexedValues.get(aCode);
	}
}

Exemple en Java 5

public enum MarquesVoitures { renault, peugeot, citroen, lada };

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.