IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

L'apparition du mot-clé const est-il prévu dans une version à venir du JDK?


Sujet :

Langage Java

  1. #21
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    605
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 605
    Points : 670
    Points
    670
    Par défaut
    class Personne implements ConstPersonne

    semble une bonne idée, mais le problème c'est que c'est cassable.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public void essai()
    {
    ConstPersonne cp = new Personne("Martin");
     
        Personne p = (Personne)cp; // Cela ne fera pas de ClassCastException puisque cp est de classe Personne!
        p.setNom("Dupont");
    }
    La solution est de faire quelque-chose (de tête) comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    /** Une personne. */
    class Personne
    {
    /** Le nom de la personne. */
    private String m_szNom;
     
       /** Construire une personne qui a un nom. */
       public Personne(String szNom) {setNom(szNom);}
     
       public interface ConstPersonne
       {
          /** Renvoyer le nom de la personne. */
          public String getNom() {return(m_szNom);}
       }
     
       /** Fixer le nom de la personne. */
       public void setNom(String szNom) {m_szNom = szNom;};
    }
    Il faut adapter un peu ce code, mais l'idée est là. on peut obtenir alors une classe de type ConstPersonne, qui n'est plus castable en Personne, ce qui était problématique. Le prix, c'est que tout ce dont pouvait hériter Personne, on en perd la notion dans l'interface interne.

    Ca reste quand-même lourd, en terme de préparation, que l'on doive construire une interface immutable ou une classe immutable (qui travaille par copie).
    const simplifierait diablement l'ensemble.

  2. #22
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    @grunt2000 :

    Je pense qu'il n'y a pas de solution en java ; il FAUT plusieurs classes, et c'est une fausse piste que de vouloir n'en faire qu'une pour traiter ce genre de problème.

    C'est ce que je fais de plus en plus pour ma part, après avoir retourné le problème dans tous les sens, et finalement c'est ce qui fonctionne le mieux.

    Il y a plein de niveaux intérmédaires, dont certains sont viables (par exemple le get sont public, tandis que les set sont package private ou protected, ce qui forme l'apparence d'une classe immuable), mais la morale de tout ça est qu'il faut deux classes, et que c'est le mieux, pour résoudre vraiment les problèmes de muabilité / immuabilité.
    Mieux que Google, utilisez Sur Java spécialisé sur la plate-forme java !
    Pour réaliser vos applications Java dans le cadre de prestations, forfait, conseil, contactez-moi en message privé.

  3. #23
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par grunt2000
    class Personne implements ConstPersonne

    semble une bonne idée, mais le problème c'est que c'est cassable.
    Le const du C++ aussi est cassable via l'opérateur const_cast il me semble...

    De toute manière l'utilisation d'un cast ne peut pas être considéré comme un oubli ou une erreur involontaire...


    Enfin si tu veux vraiment empêcher les modifs via un cast il suffit d'utiliser une classe Wrapper :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public final class ConstPersonneWrapper implements ConstPersonne {
    	private final ConstPersonne instance;
     
    	public ConstPersonneWrapper(ConstPersonne instance) {
    		this.instance = instance;
    	}
     
    	public String getNom() {
    		return instance.getNom();
    	}
    }

    Et à la rigeur tu pourrais utiliser un Proxy pour les générer dynamiquement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    	@SuppressWarnings("unchecked")
    	public static <T> T wrapper (Class<T> interfaceType, final T instance) {
    		return (T) Proxy.newProxyInstance(
    				instance.getClass().getClassLoader(),
    				new Class<?>[]{interfaceType},
    				new InvocationHandler() {
    					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    						// On redirige la méthode vers l'instance
    						return method.invoke(instance, args);
    					}
    				});
    	}
    Que tu utilises comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	Personne personne = new Personne();
    	ConstPersonne constPersonne = wrapper(ConstPersonne.class, personne);
    Et là l'instance constPersonne n'est plus castable en Personne... mais cela implique la création d'un nouvel objet...






    Citation Envoyé par grunt2000
    Ca reste quand-même lourd, en terme de préparation, que l'on doive construire une interface immutable ou une classe immutable (qui travaille par copie).
    Les classes immuables utilisent des copie seulement lorsqu'elles contiennent des objets muables, mais sinon le concept de l'immuabilité évite justement un grand nombre de copie inutile, qui en C++ sont remplacé manuellement par des références constante (const Type &).


    Si l'utilisation de const peut avoir un intérêt, il ne doit pas remplacer le concept de l'immuabilité (or on dirait que c'est ce que tu veux faire).

    L'immuabilité est un des concepts de base de Java. Si la classe String n'était pas immuable mais utilisait des const, tu devrais faire un code du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public class Personne {
     
    	private String nom;
     
    	public Personne(String nom) {
    		this.nom = nom.clone();
    	}
     
    	public void setNom(String nom) {
    		this.nom = nom.clone();
    	}
     
    	public const String getNom() const {
    		return this.nom;
    	}
    }
    Bref tout ce qu'on gagnerait ce serait des copies d'objets en plus (et plus de possibilité d'erreur de se tromper).


    Le const est plus adapté au C++ (passage par copie par défaut, appel du constructeur par copie implicitement, ...)


    a++

  4. #24
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    605
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 605
    Points : 670
    Points
    670
    Par défaut
    Si l'utilisation de const peut avoir un intérêt, il ne doit pas remplacer le concept de l'immuabilité (or on dirait que c'est ce que tu veux faire).
    C'est tout à fait ce que je veux faire. En C++, je n'ai jamais vu l'emploi d'une classe Immutable, rendu à 95% inutile grâce à const.

    L'immuabilité est un des concepts de base de Java. Si la classe String n'était pas immuable mais utilisait des const, tu devrais faire un code du genre : <suit le code>
    L'immutabilité est le palliatif de Java à son l'absence de "const-correctness". Et je me répète, mais les classes Immutables n'apportent pas la garantie de n'être pas modifiables.

    Si je reçoit un fichier TotoImmutable.class à intégrer dans mon jar, je me dis quoi? Que c'est une classe immutable ou non? D'après son nom, oui. Mais dans les faits? Il est là, le problème.

    L'exemple que tu donnes avec String est un peu biaisé car cette classe se comporte comme un type primitif.
    Et si je t'accorde que c'est une chose utile et agréable qu'il le soit, il faut considérer une classe ayant des membres d'un type autre que String et types primitifs pour étudier la constance/immuabilité.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    public class Personne
    {
    /** Date de naissance. */
    Calendar m_dtNaissance;
    
    /** Nom. */
    String m_szNom;
    
    /** Collection de prénoms de la personne. */
    Prenoms m_prenoms;
    
    
        /** Un setter d'objet immutable pour les prénoms. */
        public void setPrenoms(Prenoms prenoms)
        {
            m_prenoms = prenoms.clone(); // Ne suffirait pas. Les éléments des postes resteraient les mêmes.
    
            m_prenoms = new Prenoms();
    
            for (Prenom p : prenoms)
                m_prenoms.ajouter(p.clone());
        }
    }
    Il suffit vraiment de pas grand-chose pour se tromper régulièrement.

  5. #25
    Membre expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Points : 3 080
    Points
    3 080
    Par défaut
    Citation Envoyé par grunt2000
    Oui, absolument!

    Personne p1 = new Personne();
    const Personne p2 = new Personne();

    à partir du moment où il existe une variable autonome p1 qui se balade, et que p2 fait une simple référence à p1, si p1 est modifié, p2 le sera aussi.
    Il n'y a pas de magie dans ce cas-là: aucun moyen de l'éviter...

    En revanche, en manipulant p2 tu ne pourras rien modifier.


    C'est comme si je te donne un accès en lecture à mon compte en banque. Tu ne peux pas verser ou retirer de l'argent dessus.
    Mais si moi, dans le même temps, je conserve une autre référence dessus - elle modifiable - et que j'y mets ou que j'en retire de l'argent, eh bien nécessairement, tu verras les sommes évoluer dessus... alors que tu as un pointeur const!
    Mais l'important pour moi, c'aura été qu'en te donnant un accès const à mon compte en banque je serai sûr que toi tu ne pourras pas le modifier!

    const, ce n'est pas forcément la garantie qu'un objet garde la même valeur (ce serait trop complexe à vérifier), c'est garantir que l'on ne peut pas, soi, le modifier dans un certain périmètre.
    OK alors ça n'a plus rien à voir avec le design pattern immutable.
    Cela correspond à "vue non modifiable", comme le pattern utilisé dans la classe Collections (Collections.unmodifiableCollection(...)), qui envoie une exception au runtime.

    Autant je disais que c'était inintéressant d'utiliser const pour faire de l'immutable (car non faisable), autant pour faire une "vue non modifiable" cela serait d'après moi une avancée
    (rien que pour la méthode "unmodifiableCollection" qui ne jète une erreur qu'au runtime).

    Et je suis d'accord avec toi, ça arrive souvent qu'on veuille à partir d'un get renvoyer une référence sur un objet non modifiable en lecture, sans avoir à rediriger toutes les méthodes qui ne modifient pas l'état de l'objet.

    Donc une solution avec l'affectation dans un seul sens:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UnObjet nonModifiable = (const UnObjet) unObjet;
    Avec la déclaration des méthodes "qui ne modifient pas l'objet", il faut utiliser un autre mot-clé que const:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public const const UnObjet get() {...} //une méthode constante qui renvoie un objet constant
    Ceci n'est pas très lisible. Et il y a pire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public const UnObjet get() {...} // c'est la méthode qui est constante ou l'objet renvoyé?
    On pourrait réutiliser la syntaxe JML avec le mot-clé "pure" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public pure int get() {...} // ne modifie pas l'objet

    Et donc les variables déclarées const ne pourraient accéder qu'aux méthodes pures de l'objet référencé.

    Je suis quasiment totalement pour.
    Le seul problème c'est la compatibilité ascendante:
    - si une api rajoute dans le retour d'une méthode le mot-clé const pour indiquer qu'un objet est constant, toutes les classes qui appellent cette méthode et qui référencent l'objet dans une variable UnObjet au lieu de const UnObjet ne compileront plus...

  6. #26
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par grunt2000
    C'est tout à fait ce que je veux faire. En C++, je n'ai jamais vu l'emploi d'une classe Immutable, rendu à 95% inutile grâce à const.
    Pour moi c'est le const qui est obsolète grâce aux classes immuables

    En fait c'est surtout une différence de philosophie entre C++ et Java...
    Bien que ce soit deux langages objets avec une syntaxe relativement proche, ils n'ont pas grand chose en commum...


    Citation Envoyé par grunt2000
    L'immutabilité est le palliatif de Java à son l'absence de "const-correctness".
    L'immuabilité est l'alternative choisit par Java pour éviter la multiplication des copies implicites du C++... Elle adopte un choix différent du "const-correctness"...


    Citation Envoyé par grunt2000
    Et je me répète, mais les classes Immutables n'apportent pas la garantie de n'être pas modifiables.
    Prouve le alors !

    Si on excepte une erreur de programmation, le seul moyen de passer outre l'immuabiltié est d'utiliser la reflection (et encore cela peut être bloqué par un SecurityManager).

    Quand à la garantie du const elle est aussi cassé par le const_cast non ? (tu n'as pas répondu et je n'en suis pas sûr)


    Citation Envoyé par grunt2000
    L'exemple que tu donnes avec String est un peu biaisé car cette classe se comporte comme un type primitif.
    String est une classe immuable...


    Et je n'ai pas trop compris ton exemple avec la collections de prénoms...





    Enfin en ce qui concerne le principe de la vue non-modifiable, la solution de l'interface est toujours d'actualité :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public interface ConstPersonne {
    	public String getNom();
    }
     
    public class Personne implements ConstPersonne {
    	private String nom;
     
    	public String getNom() {
    		return nom;
    	}
     
    	public void setNom(String nom) {
    		this.nom = nom;
    	}
     
    	public ConstPersonne nonModifiableView() {
    		return this;
    	}
    }

    E si tu veux vraiment empêcher les cast il suffit d'utiliser une classe wrapper :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public final class ConstPersonneWrapper implements ConstPersonne {
    	private final ConstPersonne instance;
     
    	public ConstPersonneWrapper(ConstPersonne instance) {
    		this.instance = instance;
    	}
     
    	public String getNom() {
    		return instance.getNom();
    	}
    }
    Que tu utilises comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	public ConstPersonne nonModifiableView() {
    		return new ConstPersonneWrapper(this);
    	}
    Et à la rigueur tu peux utiliser un proxy pour générer dynamiquement le wrapper vers l'interface :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    	@SuppressWarnings("unchecked") // warning inutile car le cast ne produit pas d'erreur
    	public static <T> T wrapper (Class<T> interfaceType, final T instance) {
    		return (T) Proxy.newProxyInstance(
    				instance.getClass().getClassLoader(),
    				new Class<?>[]{interfaceType},
    				new InvocationHandler() {
    					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    						return method.invoke(instance, args);
    					}
    				});
    	}
    Que tu utilises comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	public ConstPersonne nonModifiableView() {
    		return wrapper(ConstPersonne.class, this);
    	}




    Enfin pour finir : bien sûr que le const pourrait être une solution à ce problème, mais son intégration apporterait trop de problème de compatibilité pour qu'il soit réellement utiliser massivement... ce qui lui ferait perdre tout son intérêt...


    a++

  7. #27
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Citation Envoyé par adiGuba
    Enfin en ce qui concerne le principe de la vue non-modifiable, la solution de l'interface est toujours d'actualité :
    Oui, mais je ne trouve pas ça très habile à l'usage. Il me semble que pour les immuables le mieux reste la classe pure et dure, final, etc.

    Les avantages :
    • hashcode et equals peuvent être mieux gérés
    • donc usage fiable dans les maps
    • topo similaire au niveau des classements
    • sûreté au niveau des accés concurrents des threads (forcément ! )
    • plus grande facilité de transfert entre muable et immuable

    Inconvénients :
    • aucun
    Mieux que Google, utilisez Sur Java spécialisé sur la plate-forme java !
    Pour réaliser vos applications Java dans le cadre de prestations, forfait, conseil, contactez-moi en message privé.

  8. #28
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par gifffftane
    Oui, mais je ne trouve pas ça très habile à l'usage. Il me semble que pour les immuables le mieux reste la classe pure et dure, final, etc.
    Je suis d'accord avec toi sur les avantages des classes immuables

    Mais la "vue non-modifiable" n'a pas pour objectif de "concurrencer" l'immuabilité... cela apporte une solution à un autre problème (une vue en "read-only" sur un objet mutable).

    a++

  9. #29
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Citation Envoyé par adiGuba
    Mais la "vue non-modifiable" n'a pas pour objectif de "concurrencer" l'immuabilité... cela apporte une solution à un autre problème (une vue en "read-only" sur un objet mutable).

    a++
    Pour cet usage, je préfère passer par la méthode clone, que je trouve injustement délaissée par les programmeurs.

    Il me semble que cela résoud le problème de protéger une valeur interne, en laissant ouvert à l'extérieur toutes les fonctions et les valeurs d'une classe. Donc c'est mieux Et là, aucun besoin d'écrire des interfaces de plus.

    Bien sûr, il faut régler la profondeur du clone... mais cela me parait une démarche assez naturelle et assez claire... du moins s'il n'y avait pas tous ces préjugés sur cette méthode.
    Mieux que Google, utilisez Sur Java spécialisé sur la plate-forme java !
    Pour réaliser vos applications Java dans le cadre de prestations, forfait, conseil, contactez-moi en message privé.

  10. #30
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par gifffftane
    Pour cet usage, je préfère passer par la méthode clone, que je trouve injustement délaissée par les programmeurs.
    Ce n'est pas la même chose puisque dans ce cas tu as deux objets distincts

    La "vue non-modifiable" permet de voir les modifications qui sont faite sur la classe originale, tout en lui interdisant de la modifier.

    Bref la vue non-modifiable permet d'interdire d'utiliser un setter...

    a++

  11. #31
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    605
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 605
    Points : 670
    Points
    670
    Par défaut
    Zéro inconvénients. Allons!

    Inconvénients:
    - si c'est une classe immutable qui est réalisée, travaillant en interne sur une copie de données.
    • Il y a consommation de temps système, de ressources mémoire.
    • Il faut créer un code dédié pour les setters ou mettre en place une solide méthode clone(). Il existe donc deux implémentations d'une classe. La classe A et la classe AImmutable. Le projet grandit, porteurs d'objets - pardon - encombrants.
    • Le nombre de bugs possibles lors de l'écriture d'un clone est important. Il est vraiment très facile de se tromper. Et quand on s'est trompé, sa classe immutable ne vaut plus rien.


    - Si l'immuabilité est réalisée par une interface reprenant les getters et non une classe dédiée alors:
    • 20% (au moins) des développeurs se trompent et écrivent:
      class Personne extends ConstPersonne, ce qui est une faute.
    • Si l'on fait une interface interne, qui protège effectivement l'objet, c'est lourd à implémenter.
    • Dans ce cas de figure, le comportement se rapproche du const avec sa "faiblesse":
      Si AImmutable pointe sur A et que A évolue, AImmutable le verra. Dans le cas d'une classe Immutable pure copie (plus haut) AImmutable ne le verrait pas.

  12. #32
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Citation Envoyé par adiGuba
    Ce n'est pas la même chose puisque dans ce cas tu as deux objets distincts
    Je le sais bien que ce n'est pas la même chose. Je considère que ce que je propose est mieux ; je n'aime pas beaucoup, je l'admets, le concept de vue non modifiable, qui me parait une mauvaise solution, du moins avec ce que l'on dispose en java.
    Citation Envoyé par adiGuba
    La "vue non-modifiable" permet de voir les modifications qui sont faite sur la classe originale, tout en lui interdisant de la modifier.

    Bref la vue non-modifiable permet d'interdire d'utiliser un setter...

    a++
    Je vais être provocateur : et alors ?? à quoi cela sert-il ?

    Moi aussi j'ai inventé quantité d'interfaces etc pour protéger des valeurs... j'étais souvent peu satisfait du résultat, qui me coutait beaucoup de temps et que n'importe quel stagiaire débutant pouvait contourner facilement de toutes façons.

    Il me semble qu'il vaut mieux traiter les choses en correspondance avec le domaine que l'on exprime, et que les protections s'établissent quasiment d'elles mêmes.

    S'il apparaît des risques d'interventions intenpestives, alors il vaut mieux résoudre les choses par le biais de l'état de l'objet, ou de la connaissance de son contexte, bref par la robustesse. Finalement, faire des objets très ouverts, capables de répondre à tout, mais pas n'importe comment ; toujours de façon adéquate. C'est là que se trouve la véritable protection.

    Cette approche me semble beaucoup plus efficace que le concept de vue non modifiable, casse gueule en java. En d'autres langages, peut être, en java, bof bof.

    Et puis au fait tant qu'on y est, une autre technique utile et mieux que l'idée de la vue non modifiable est celle du listener (entre écouter et voir, y a-t-il une différence ? ), qui demande à réfléchir sur qui écoute quoi.
    Mieux que Google, utilisez Sur Java spécialisé sur la plate-forme java !
    Pour réaliser vos applications Java dans le cadre de prestations, forfait, conseil, contactez-moi en message privé.

  13. #33
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Citation Envoyé par grunt2000
    Zéro inconvénients. Allons!

    Inconvénients:
    - si c'est une classe immutable qui est réalisée, travaillant en interne sur une copie de données.
    • Il y a consommation de temps système, de ressources mémoire.
    • Au niveau de la consomation des ressources, il faut toujours comparer deux solutions, donc deux consomations. Evidemment qu'une solution consome des ressources, mais ce n'est pas un défaut en soi.

      Ici au niveau de la solution classe / classe immuable : deux classes. C'est pas mal non ? Il y a mieux en java ??


      Citation Envoyé par grunt2000
    • Il faut créer un code dédié pour les setters ou mettre en place une solide méthode clone(). Il existe donc deux implémentations d'une classe. La classe A et la classe AImmutable. Le projet grandit, porteurs d'objets - pardon - encombrants.
    D'abord il existe une parentée entre la classe muable et son vis-à-vis immuable, mais ce n'est pas la même implémentation d'une classe parente. C'est une erreur que je commaittais au départ, et que j'essaie de ne plus commettre aujourd'hui. Il faut plutôt voir la classe immuable comme une sorte de clef, qui te donne accés, ou qui te permets de repérer, ou qui te permets de sanctuariser, une valeur muable.

    En fait les deux valeurs - muable et immuable - ne sont pas utilisés dans les mêmes contextes, et donc n'ont pas les mêmes méthodes, les mêmes propos.

    Citation Envoyé par grunt2000
  14. Le nombre de bugs possibles lors de l'écriture d'un clone est important. Il est vraiment très facile de se tromper. Et quand on s'est trompé, sa classe immutable ne vaut plus rien.
Citation Envoyé par grunt2000
Peut être. Là encore, il faut comparer avec les autres solutions. Dans l'implémentation d'une interface, je n'ai jamais eu la sensation d'être très protégé.
Citation Envoyé par grunt2000
- Si l'immuabilité est réalisée par une interface reprenant les getters et non une classe dédiée alors:
  • 20% (au moins) des développeurs se trompent et écrivent:
    class Personne extends ConstPersonne, ce qui est une faute.
Oui et non. Classes muables et immuables évoluent de façon indépandantes.
Donc...
Mieux que Google, utilisez Sur Java spécialisé sur la plate-forme java !
Pour réaliser vos applications Java dans le cadre de prestations, forfait, conseil, contactez-moi en message privé.

  • #34
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par grunt2000
    - si c'est une classe immutable qui est réalisée, travaillant en interne sur une copie de données.
    Cela dépend des données que tu utilises !

    Essayes de coder ta classe Personne en utilisant un StringBuffer (donc une classe muable) au lieu d'une String (qui est immuable), et tu verras que tu te retrouveras avec bien plus de copie de données...


    Citation Envoyé par grunt2000
    Il y a consommation de temps système, de ressources mémoire.
    Faux les classes immuables permettent justement d'éviter des copies inutiles. Ce sont les classes muables qui impliques l'utilisation de ces copies !

    Citation Envoyé par grunt2000
    Il faut créer un code dédié pour les setters
    Seulement pour les setters des attributs muables

    Citation Envoyé par grunt2000
    ou mettre en place une solide méthode clone().
    Une classe immuable n'a pas besoin d'être cloner !!! A quoi cela pourrait-il bien servir ???

    Citation Envoyé par grunt2000
    Il existe donc deux implémentations d'une classe. La classe A et la classe AImmutable.
    Le seul point où je suis d'accord : on peut avoir besoin de deux implémentations (même si ce n'est pas forcément une obligation).
    L'implémentation immuable permet de partager la référence librement sans craindre qu'elle ne soit modifié.
    L'implémentation muable doit être utilisé de manière restreinte si on veut contrôler son état.

    Citation Envoyé par grunt2000
    Le nombre de bugs possibles lors de l'écriture d'un clone est important. Il est vraiment très facile de se tromper. Et quand on s'est trompé, sa classe immutable ne vaut plus rien.
    Mais les classes immuables n'ont pas besoin d'être cloné... As-tu vu une implémentation de clone() dans la classe String ?

    Citation Envoyé par grunt2000
    - Si l'immuabilité est réalisée par une interface reprenant les getters et non une classe dédiée alors:
    Alors ce n'est pas de l'immuabilité mais une "vue"...

    Citation Envoyé par grunt2000
    20% (au moins) des développeurs se trompent et écrivent:
    class Personne extends ConstPersonne, ce qui est une faute.

    ...
    A aprtir de là je t'ai un peu perdu car je ne comprend pas trop ce que tu veux dire...



    Citation Envoyé par gifffftane
    Et puis au fait tant qu'on y est, une autre technique utile et mieux que l'idée de la vue non modifiable est celle du listener (entre écouter et voir, y a-t-il une différence ? ), qui demande à réfléchir sur qui écoute quoi.
    Justement cela peut être un cas d'utilisation de la vue non-modifiable : tu veux que les listeners puissent avoir accès aux valeurs des attributs de ton objet muable, mais qu'il ne puisse pas le modifier...

    Donc soit tu utilises un objet Event immuable qui contiendrait une copie des attributs, soit tu utilises un wrapper qui ne te permettent que de voir les attribut...

    Pour moi immuabilité et vue non-modifiable sont deux choses très différentes

    a++

  • #35
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    605
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 605
    Points : 670
    Points
    670
    Par défaut
    Bon on va se mettre d'accord sur un exemple.

    Voici cette classe:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    /**
     * Une commande de client.
     */
    public class BonDeCommande
    {
    /** Le client qui a commandé. */
    private Client m_client;
     
    /** Le prix total de sa commande. */
    private double m_dPrix;
     
    /** La composition de sa commande. */
    private Vector<Article> m_composition;
     
        public BonDeCommande() {...}
        public Client getClient() {...}
        public double getPrix() {...}
        public Vector<Article> getArticles() {...}
        public void setClient(Client client) {...}
        public void setPrix(double prix) {...}
        public void setArticles(Vector<Articles> articles) {...}
    }
    Comment créez-vous soit votre classe soit votre interface (comme vous préférez) immutable à partir de celle-ci?

    Et comment l'employez-vous?

    J'ai une instance d'un bon de commande de noël à ma disposition,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    BonDeCommande commandeDeNoel = new BonDeCommande();
    Vector<Article> cadeaux = new Vector<Article>();
    cadeaux.add(new Article("Train électrique"));
    cadeaux.add(new Article("Puzzle"));
    commandeDeNoel.setArticles(cadeaux);
    commandeDeNoel.setPrix(15);
    commandeDeNoel.setClient(new Client("Ernest le bel"));

    et je veux retourner un immutable de cet instance d'objet, commandeDeNoel, sous le nom commandeDeNoelConstante. Comment procédez-vous?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    BonDeCommandeImmutable commandeDeNoelConstante = ... ?

  • #36
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Question : pourquoi ? Et qui veut retourner une instance immuable, qui en a besoin ?

    Dans les cas où il n'y a pas de raison particulière, seulement une sorte de crainte que des développements futurs mettent le bazard dans des objets que j'ai peur que tout le monde modifie sans prévenir, alors j'utilise clone, c'est tout.

    Je trouve ça très pratique, parce que cela implique de réfléchir aux composants de l'objet (pour savoir comment gérer le clone en profondeur), réflexion qui servira plus tard à décider ce qu'il faudra retenir pour l'immuable.

    Ici, ce qui est intéressant, ce n'est pas vraiment de savoir s'il faudrait sous-cloner le Vector des articles, mais plutôt de savoir s'il faut cloner le client. En effet, cloner un client, à ce stade, cela ne veut sans doute pas dire grand chose.

    Donc la notion de constante sur un bon de commande implique la notion de constante sur le client. Etc.

    Et grâce au concept du clone, on peut mener et expérimenter cette réflexion avec un impact minima sur le code.

    De plus, comme l'ensemble des fonctions et propriétés de l'objet reste actif, on peut le soumettre à un plus grand nombre d'épreuves et de contraintes, de cas d'usages, qui affineront sa définition, et, peut être, aboutiront à d'autres choses que d'être de stupides constantes ; par exemple des classes plus adaptées à la GUI, ou à la sauvegarde, ou que sais-je.
    Mieux que Google, utilisez Sur Java spécialisé sur la plate-forme java !
    Pour réaliser vos applications Java dans le cadre de prestations, forfait, conseil, contactez-moi en message privé.

  • #37
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par grunt2000
    Comment créez-vous soit votre classe soit votre interface (comme vous préférez) immutable à partir de celle-ci?
    Attention : on n'a pas parlé "d'interface immuable" (ce qui est impossible puisque l'immuabilité est une spécificité de l'implémentation) mais de "vue non-modifiable" (ce qui se rapproche le plus du concept du const...



    Enfin pour faire une classe immuable, il faut d'abord savoir si les attributs qui les composent sont muable ou pas. Donc il nous faut au moins que tu répondes aux infos suivantes :

    • La classe Client est-elle immuable ou pas ?
    • La classe Vector (j'aurais plutôt utilisé List dans une signature de méthode) est muable, mais qu'en est-il de la classe Article ? Muable ou pas ?


    De plus ces réponses ont également une influence sur le code de ta classe muable BonDeCommande, donc ce serait bien que tu donnes le code complet pour comparer


    a++

  • #38
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    605
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 605
    Points : 670
    Points
    670
    Par défaut
    Je vais simplifier le problème ainsi.

    Cet objet BonDeCommande, j'en possède une instance nommée bonDeCommande.

    Je veux transmettre cette instance de BonDeCommande à cette fonction qui en a besoin:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public void ignobleFélon(.... bonDeCommande)
    {
    }
    Et comme je n'ai très confiance en elle, j'ai décidé de ne pas lui donner l'objet original.

    soit ainsi:
    public void ignobleFélon(BonDeCommandeImmutable bonDeCommande)

    en transmettant un objet "Immutable" basé sur une copie de l'instance bonDeCommande que j'ai, ou selon n'importe quel procédé de votre imagination qui la protègera.

    soit de cette manière:
    public void ignobleFélon(BonDeCommandeConst bonDeCommande)
    En utilisant une sous-interface "constante".


    Les membres de la classe BonDeCommande (Client, Article) ne sont pas immutables eux-mêmes au démarrage du problème posé.

  • #39
    Membre émérite
    Avatar de gifffftane
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 354
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire (Rhône Alpes)

    Informations forums :
    Inscription : Février 2007
    Messages : 2 354
    Points : 2 582
    Points
    2 582
    Par défaut
    Je ne sais pas si l'exercice a un sens, mais enfin moi je clonerais tout, si tout est clonable. Sinon, je créerais un nouvelle objet BonDeCommande avec de nouveaux Clients et Articles, si je peux créer ces objets là. Si je ne peux pas le faire, alors je créerais une classe qui fasse toutes les interfaces (gros boulot, qui immanquablement, me fera penser que tout cela est complètement inutile et qu'en réfléchissant un petit peu, c'est à dire en changeant l'approche du problème, je trouverai quelque chose de mieux).

    Donc, moralité : change l'approche du problème.

    Au lieu de penser technique avec les const, pense cas d'usage utilisateur, et à ce que cela t'apprend sur son monde à lui.
    Mieux que Google, utilisez Sur Java spécialisé sur la plate-forme java !
    Pour réaliser vos applications Java dans le cadre de prestations, forfait, conseil, contactez-moi en message privé.

  • #40
    Membre éclairé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    605
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 605
    Points : 670
    Points
    670
    Par défaut
    J'ai du mal à vous comprendre. Au début de ce message, j'ai dit que j'appelais de mes voeux l'arrivée du mot-clé const en java pour résoudre une gamme de problèmes que final ne parvient pas à traiter.

    Vous m'avez répondu qu'une classe immutable était ce qui se faisait de mieux pour traiter les problèmes que j'évoquais, et que cette pratique n'avait même aucun inconvénient.

    Et à présent que je demande son illustration sur un exemple concret, vous me répondez: "Changes-donc ton énoncé!". Et ainsi, vous ne répondez pas à la question posée.

    Moi je dis: java manque du mot-clé const, de manière définitive. Parce que si je l'avais, je confierais mon instance à une fonction seulement si elle me propose ce prototype:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public void ignobleFélon(const BonDeCommande bonDeCommande)
    {
    }
    Et ma classe BonDeCommande aurait été modifiée ainsi:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    /**
     * Une commande de client.
     */
    public class BonDeCommande
    {
    /** Le client qui a commandé. */
    private Client m_client;
     
    /** Le prix total de sa commande. */
    private double m_dPrix;
     
    /** La composition de sa commande. */
    private Vector<Article> m_composition;
     
        public BonDeCommande() {...}
        public Client getClient() {return(m_client);} // Modifiable.
        public const Client getClient() const {return(m_client);} // Non modifiable.
     
        public double getPrix() const {return(m_dPrix);}
     
        public Vector<Article> getArticles() {return(m_articles);} // Modifiable
        public const Vector<const Article> getArticles() const {return(m_articles);} // Non modifiable.
     
        public void setClient(Client client) {...}
        public void setPrix(double prix) {...}
        public void setArticles(Vector<Articles> articles) {...}
    }
    Si vous pensez que vos pratiques de codage sont supérieures à ce qu'apporterait le mot-clé const, puisque vous le critiquez, pourquoi ne pas m'en donner une illustration sur l'exemple que je vous donne?

    Là, nous pourrons peser le pour et le contre!

  • + Répondre à la discussion
    Page 2 sur 3 PremièrePremière 123 DernièreDernière
    ActualitésFAQs JavaTutoriels JavaLivres JavaSources JavaOutils, EDI & API JavaJavaSearch

    Discussions similaires

    1. Réponses: 10
      Dernier message: 23/10/2009, 10h04
    2. Réponses: 6
      Dernier message: 06/08/2009, 15h22
    3. Réponses: 4
      Dernier message: 25/11/2007, 22h30
    4. Réponses: 5
      Dernier message: 07/09/2007, 18h23
    5. mandriva est il disponible dans sa version finale ?
      Par kerkennah dans le forum Mandriva / Mageia
      Réponses: 7
      Dernier message: 25/05/2007, 23h37

    Partager

    Partager
    • Envoyer la discussion sur Viadeo
    • Envoyer la discussion sur Twitter
    • Envoyer la discussion sur Google
    • Envoyer la discussion sur Facebook
    • Envoyer la discussion sur Digg
    • Envoyer la discussion sur Delicious
    • Envoyer la discussion sur MySpace
    • Envoyer la discussion sur Yahoo