On Thu, 12 Jun 2003 13:35:22 +0200, St�phan BERNARD <[EMAIL PROTECTED]> wrote:

Bonjour la liste,

j'ai rencontr� deux fois en peu de temps des contextes o� l'on aimerait avoir
des m�thodes ou des attributs statiques ET abstraits :

D'abord un petit rappel, pour bien pr�ciser nos id�es communes sur les choses dont on parle.
En Java, les m�thodes et variables statiques sont associ�es � une classe, et ce sans notion d'h�ritage. C'est-�-dire que si B h�rite de A, et qu'on d�finit dans A une variable statique a, elle sera inaccessible aux m�thodes statiques de B, mais pas aux instances de B, qui sont, elles �galement des instances de A, par le biais de l'h�ritage, justement.
C'est � mon sens une faiblesse de Java, mais on n'y peut rien !

1er exemple : On a une classe abtraite A et deux classes B et C qui h�ritent de A. Un attribut (appelons-le "val") est commun � tous les B et � tous les C (mais n'a pas la m�me valeur pour les B et pour les C).

Il pourrait donc, � priori, s'agir d'une variable statique des classes B et C. Si du moins tu disposais d'un moyen d'acc�der aux classes B et C.
Pourquoi, dans ce cas, ne pas simplement d�clarer dans chacune des classes o� c'est n�cessaire cet attribut static, et y acc�der directement ?
D'un seul coup, on peut constater que cette m�thode est ignominieuse, et ne convient donc pas.


D'un c�t�, on aimerait conna�tre val pour un A quelconque
(instanci� indiff�ramment en B ou C), mais d'autre part, on veut pouvoir
conna�tre cette valeur sans avoir d'instance de B ou de C (d'o� le static).


Comment faire ceci proprement ?

En fait, il s'agit, comme toujours, d'un probl�me de design. Ces variables val peuvent �tre obtenues par le biais d'une m�thode, d�finie dans la classe A et static, en utilisant le bon pattern. Je ne connais pas son nom, mais l'id�e est bien simple.
Si tu utilises dans cette fameuse m�thode de A un objet d'une autre classe (appelons-la ValRepository) � laquelle tu passes la classe de l'objet appelant, rien ne t'emp�che de stocker dans ce ValReposiry (qui lui impl�mente le pattern singleton) tous les "val" dont tu as besoin avec les bonnes valeurs.
Et rien ne t'emp�che, pour conserver un vrai design orient� objet, de parcourir de mani�re ascendante la hi�rarchie de ta classe � la recherche d'une classe pour laquelle val est connue.
R�sumons-nous.
Dans A, tu as une m�thode getVal qui fait ceci :
public static Val getVal(Class callerClass) {
return ValRepository.getInstance().getVal(callerClass);
}


Et dans ta classe ValRepository, tu cr�es une Map qui associe � chacune des classes pour lesquelles elle est d�finie la valeur de Val.
Soit :
protected Map valMap = new HashMap();
valMap.put(A.class, val1);


Et la m�thode getVal est :

public Val getVal(Class callerClass) {
        Val returned = valMap.get(callerClass);
// Ici, il faut g�rer en plus le cas de la remont�e jusqu'� Class.
        if(returned==null) returned = getVal(callerClass.getSuperClass());
        return returned;
}

Et bien s�r, pour �viter le probl�me de la remont�e jusqu'� Val, tu vas penser � passer un objet de la classe A, et faire le getClass dans ValRepossitory. Comme tu es malin ;-)

2�me exemple :
En gardant telles quelles les classes A, B et C, je me trouve dans un contexte
o�, selon les param�tres pass�s au constructeur de B, celui-ci aura :
- soit un comportement identique � C
- soit un comportement particulier � B.
Bien s�r, je peux faire h�riter B de C, mais il faudra que je teste dans toutes les m�thodes
de B le comportement � avoir pour, soit appeler la m�thode de C, soit calculer le r�sultat
dans B.

Tu dois vraiment faire �a pour toutes les m�thodes ?


Mais cette solution ne me satisfait pas, � cause de la lourdeur du code d'une part,
et � cause de la non-n�cessit� de me trimballer les volumineux attributs de C lorsque B
doit avoir un comportement particulier.

Et utiliser le pattern Delgate ? B peut, dans les cas utiles, faire appel � un objet C ...

La solution qui me plairait serait d'ajouter une m�thode statique getInstance() qui renvoie un A.
Et comme j'aimerais g�n�raliser cette pratique � toutes mes classes, je voudrais
mettre cette m�thode en abstract dans A.

Je ne comprend pas le lien entre d'un c�t�, l'utilisation d'un Delegate dans B, et d'un autre, le passage � une m�thode statique getInstance dans A.

Bien s�r, je n'ai jamais besoin d'appeler A.getInstance() et je peux compter
sur la rigueur des d�veloppeurs pour impl�menter syst�matiquement cette m�thode
dans toutes les classes qui h�ritent de A.
Mais je suis moyennement satisfait de cette solution.

En fait, l'id�e est d'utiliser exactement le principe du ValRepository, mais pour des objets de la classe A. C'est-�-dire retourner un objet d'une sous-classe de A d�pendant de l'objet pass� en param�tre.

Quelqu'un conna�t-il un moyen de rendre obligatoire l'�criture de cette m�thode
statique dans toutes les classes qui impl�mentent A ?

L'avantage du pattern repository (je vais l'appeler comme �a, m�me si �a n'est pas le cas), c'est que tu n'as qu'une impl�mentation, qu'il faut effectivement penser � mettre � jour en fonction des classes de tes objets, mais �a peut �tre fait par le biais d'un bloc d'initialisation static dans tes diff�rentes classes, et que cette impl�mentation couvre tous tes besoins, alors que tes m�thodes statiques doivent �tre disponibles dans chaque sous-classe, ce qui me semble une faille conceptuelle importante.

Merci d'avance, St�phan BERNARD




--
Nicolas Delsaux
"Ia d�mocratie est la pire des dictatures parce qu'elle est la dictature exerc�e par le plus grand nombre sur la minorit�."




Répondre à