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. #41
    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
    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.
    Ces deux mot-clefs n'ont pas du tout le même objectifs...


    Citation Envoyé par grunt2000
    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.
    Disons que l'utilisation des const est remplacé par des classes immuables...

    Citation Envoyé par grunt2000
    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.
    Non j'ai juste demandé des informations supplémentaires

    Le problème n'est pas le même : si ta classe aurait été immuable tu n'aurais pas eu à utiliser const...





    Lorsqu'un bon de commande est créé il ne varie plus, donc il est inutile d'avoir à modifier ses attribut...

    Perso j'aurais donc utiliser seulement des classes immuables (avec eventuellement un Builder pour les créer), par exemple si Client et Article sont immuable, j'écrirais écrit 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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    public final class BonDeCommande
    {
    	/** Le client qui a commandé. */
    	private final Client client;
     
    	/** Le prix total de sa commande. */
    	private final double prix;
     
    	/** La composition de sa commande. */
    	private final List<Article> articles;
     
        public BonDeCommande(Client client, List<Article> articles) {
        	this.client = client;
        	// On protège la List qui est un objet modifiable
        	this.articles = Collections.unmodifiableList(new ArrayList<Article>(articles));
        	double p = 0;
        	for (Article a : this.articles) {
        		p += a.getPrix();
        	}
        	this.prix = p;
        }
     
        public Client getClient() {
        	return client;
        }
     
        public double getPrix() {
        	return prix;
        }
     
        public Iterable<Article> getArticles() {
        	return articles;
        }
    }





    Maintenant si tu as une classe muable :

    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    public class BonDeCommande
    {
    	/** Le client qui a commandé. */
    	private final Client client;
     
    	/** Le prix total de sa commande. */
    	private final double prix;
     
    	/** La composition de sa commande. */
    	private final List<Article> articles;
     
     
        public Client getClient() {
        	return client;
        }
     
        public double getPrix() {
        	return prix;
        }
     
        public void setClient(Client c) {
        	this.client = c;
        }
     
        public void setPrix(double d) {
        	this.prix = d;
        }
     
        public void addArticle(Article a) {
        	this.articles.add(a);
        }
     
        public Iterable<Article> getArticles() {
        	return articles;
        }
     
    }

    Et que tu veux reprendre le principe du const il faut utiliser une interface qui serait implémenté par ta classe principale :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public interface BonDeCommandeInterface {
    	public Client getClient();
     
    	public double getPrix();
     
    	public Iterable<Article> getArticles();
    }
    Et là tu obtiens les mêmes possibilités qu'avec un const sur une classe mutable...






    Citation Envoyé par grunt2000
    Si vous pensez que vos pratiques de codage sont supérieures à ce qu'apporterait le mot-clé const, puisque vous le critiquez,
    On ne le critique pas et on n'a pas dit qu'il s'agissait d'une pratique meilleure !

    On a simplement dit que l'immuabilité est plus dans la philosophie de Java... alors que tu adoptes plus une approche C++ pas très adapté à Java (et donc tu déplores l'absence du const primordiale en C++)


    a++

  2. #42
    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
    Dans:

    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
    29
    30
    31
    32
    33
    34
    35
     
    public final class BonDeCommande
    {
    	/** Le client qui a commandé. */
    	private final Client client;
     
    	/** Le prix total de sa commande. */
    	private final double prix;
     
    	/** La composition de sa commande. */
    	private final List<Article> articles;
     
        public BonDeCommande(Client client, List<Article> articles) {
        	this.client = client;
        	// On protège la List qui est un objet modifiable
        	this.articles = Collections.unmodifiableList(new ArrayList<Article>(articles));
        	double p = 0;
        	for (Article a : this.articles) {
        		p += a.getPrix();
        	}
        	this.prix = p;
        }
     
        public Client getClient() {
        	return client;
        }
     
        public double getPrix() {
        	return prix;
        }
     
        public Iterable<Article> getArticles() {
        	return articles;
        }
    }
    C'est ok, mais tu dois placer un :
    this.client = (Client)client.clone();
    dans ton constructeur, à mon avis.

    Car ton private final Client client
    n'empêchera pas la modification du Client qui aura été renvoyé par getClient().


    Si tu utilises l'interface

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public interface BonDeCommandeInterface {
    	public Client getClient();
     
    	public double getPrix();
     
    	public Iterable<Article> getArticles();
    }
    Ca peut marcher, sauf si tu l'utilises ainsi:
    public BonDeCommande extends BonDeCommandeInterface

    Car sinon, je peux écrire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    public void ignobleFélon(BonDeCommandeInterface commande)
    {
        BonDeCommande bc = (BonDeCommande)commande;
        bc.setPrix(10);
    }
    Et j'aurai modifié ta commande.

  3. #43
    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 ok, mais tu dois placer un :
    this.client = (Client)client.clone();
    dans ton constructeur, à mon avis.

    Car ton private final Client client
    n'empêchera pas la modification du Client qui aura été renvoyé par getClient().
    Non car j'ai supposé que les classes Client et Article étaient immuables
    Sinon c'est vrai qu'il faudrait en faire une copie (mais dans ce cas on devrait alors le faire même si la classe est muable).



    Citation Envoyé par grunt2000
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    public void ignobleFélon(BonDeCommandeInterface commande)
    {
        BonDeCommande bc = (BonDeCommande)commande;
        bc.setPrix(10);
    }
    Et j'aurai modifié ta commande.
    Tu peux faire la même chose avec const_cast (mais je ne suis plus sûr de la syntaxe exacte) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    public void ignobleFélon(const BonDeCommande commande)
    {
        BonDeCommande bc = const_cast<BonDeCommande>(commande);
        bc.setPrix(10);
    }
    Et pour l'empêcher il suffit d'utiliser une classe wrapper comme je l'ai indiqué précédemment ( http://www.developpez.net/forums/sho...4&postcount=23 )

    a++

  4. #44
    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
    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.
    Oui enfin... c'est assez raccourci. Nous avons également dit que cela se faisait en fonction du domaine, que c'était ce dernier qui justifiait l'immuabilité d'une valeur, y compris au niveau de ces fameuses gammes de problèmes que final ne pourrait pas traiter, et pas les précautions qu'un programmeur voudrait prendre sous prétexte de sécurité, et que à partir de là, 9 fois sur 10, d'autres solutions, telles que la vue en lecture seule, ou la classe immuable étaient de bonnes solutions.

    Et nous avons également reconnu qu'il manquait certainement un mot clef à java, ou quelque chose, pour marquer le fait d'être en lecture seule.

    Par contre, là où nous ne sommes pas d'accord, je pense, est que nous pensons que c'est une fausse piste que de transformer un objet modifiable en un objet en lecture seule, par un simple mot clef.

    Cela n'empeche pas que cela existe dans un langage ; nous pensons simplement que c'est une mauvaise solution à un vrai problème.

    Dans le cas où cela existe, alors c'est evidemment plus facile à écrire. Mais cela reste une fausse piste. Juste une fausse piste facile à écrire.
    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é.

  5. #45
    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 ne comprends pas en quoi l'emploi du mot-clé const est une fausse piste.

    Peux-tu exposer un cas où son emploi conduit à une erreur?


    @adiGuba:
    Tu as raison de souligner que const_cast<...> a été un opérateur extrêmement décrié en C++. Mais l'on peut supposer que si const était repris en Java, Sun ne commettrait pas la bêtise d'implanter cette catastrophe-là. Il y en avait d'autres, dans le même genre. reinterpret_cast, en particulier.

    Et pour l'empêcher il suffit d'utiliser une classe wrapper comme je l'ai indiqué précédemment ( http://www.developpez.net/forums/sho...4&postcount=23 )
    Il suffit? As-tu bien lu le code que tu proposes? Même s'il est bon (à démontrer), il apparaît comme une patouille.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    @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);
    					}
    				});
    	}
    Il met en exergue la propreté et la commodité de const face à toutes les constructions plus ou moins complexes, plus ou moins solides, plus ou moins démontrées, qui voudraient remplacer son emploi.

  6. #46
    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 disais que la transformation, par un mot clef, de quelque chose de muable en quelque chose d'immuable était une fausse piste. Le mot clef const lui même, je m'en fous.

    Cela ne me semble pas crédible de transmettre quelque chose à quelqu'un d'autre en lui disant : Ceci tu pourrais le modifier mais attention tu n'en as pas le droit. S'il a besoin de le modifier, alors il trouvera toujours une combine, et s'il n'en a pas besoin, alors il ne le fera pas.

    Dans ton exemple et ta solution, rien ne dit que l'utilisateur de ton BonDeCommande n'aura pas besoin de modifier la liste des articles, et en ce cas il trouvera les moyens de le faire, quelque soit les const et autres dont on aura affublé le code. C'est là dessus que l'on tique, et pas sur le fait que le terme const est rapide à écrire.

    Maintenant, que ce soit moi ou d'autres, on admet qu'il serait utile de marquer une classe ou une interface déjà construite comme étant en lecture seule. Je veux dire que cette chose ne sera pas transformée, mais qu'elle est. Un String est en lecture seule ; un StringBuffer, non. Je crois qu'il serait bon de pouvoir marquer String, mais pas d'interdire ponctuellement par un mot clef d'écrire un StringBuffer.
    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é.

  7. #47
    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 gifffftane
    Cela ne me semble pas crédible de transmettre quelque chose à quelqu'un d'autre en lui disant : Ceci tu pourrais le modifier mais attention tu n'en as pas le droit. S'il a besoin de le modifier, alors il trouvera toujours une combine, et s'il n'en a pas besoin, alors il ne le fera pas.
    Si c'est crédible.
    Par exemple, tu veux transmettre à ta vue une liste d'éléments du modèle.
    Tu pourrais imaginer lui transmettre ta List<UnObjet>, mais tu ne veux pas car il pourrait faire un .add(...) qui rendrait la gestion de ton modèle totalement incohérente.
    Ce que tu es obligé de faire pour garantir cela actuellement, c'est de renvoyer un Collections.unmodifiableList(taListe) (une vue non modifiable, mais dont le pattern laisse à désirer - jète une exception au runtime).
    Si le const était implémenté, il n'y aurait pas de "combine" pour le modifier...

  8. #48
    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 ®om
    Si c'est crédible.
    Par exemple, tu veux transmettre à ta vue une liste d'éléments du modèle.
    Tu pourrais imaginer lui transmettre ta List<UnObjet>, mais tu ne veux pas car il pourrait faire un .add(...) qui rendrait la gestion de ton modèle totalement incohérente.
    Je n'ai pas la même opinion

    Si tu veux transmettre une liste d'éléments, liste non modifiable, alors c'est qu'il y a une raison en rapport avec l'usage, et le domaine, et donc, quelque part, tu dois imaginer une classe qui exprimerait cela.

    C'est en recherchant cette classe que tu construiras un ensemble cohérent, et non pas en te protégeant d'usages qui seraient mauvais.

    Je sais bien que dans le jdk il n'y a que des trucs bancals au sujet des listes en lecture seule, et cela m'a souvent dérangé. Donc je fais des listes à moi, sans add. (en général un tableau, tout simplement).

    Citation Envoyé par ®om
    Ce que tu es obligé de faire pour garantir cela actuellement, c'est de renvoyer un Collections.unmodifiableList(taListe) (une vue non modifiable, mais dont le pattern laisse à désirer - jète une exception au runtime).
    Si le const était implémenté, il n'y aurait pas de "combine" pour le modifier...
    Peut être. (enfin... certainement...)

    Mais le problème fondamental demeure : l'objet que tu transmets est inadapté à son usage, puisqu'il comporte des méthodes que tu dois masquer, au risque de rendre la gestion de ton modèle incohérente. Si la gestion d'un modèle est incohérente, c'est que le modèle est incohérent.

    Bien sûr, rien n'est parfait, etc, aussi je conçois que l'usage d'un mot clef pourrait permettre certaines adaptations diverses. J'ai moi même bien d'autres combines approximatives.

    Je pense qu'il y aurait meilleur compte à définir et à pouvoir marquer ce qu'est un objet fixe, ou constant, ou immuable, peut être dans l'approche des effets de bord (pour dire qu'il n'y en a pas, bien sûr).
    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é.

  9. #49
    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
    Je ne comprends pas en quoi l'emploi du mot-clé const est une fausse piste.
    C'est une "fausse piste" en Java !

    Ce n'est pas parce que c'est ce qui est utilisé pour coder en C++ que c'est forcément ce qui devrait être utilisé en Java. Ce sont deux langages très différents avec des philosophies assez éloignés...

    L'utilisation du const aurait pu être une solution en Java s'il aurait été utilisée depuis le début, mais ce n'est pas le cas et l'utilisation des interfaces lui a été privilégié. Personnellement je ne vois pas de grosse différence entre les deux solutions sur le point de vue des possibilités offertes.




    Citation Envoyé par grunt2000
    Et pour l'empêcher il suffit d'utiliser une classe wrapper comme je l'ai indiqué précédemment ( http://www.developpez.net/forums/sho...4&postcount=23 )
    Il suffit? As-tu bien lu le code que tu proposes? Même s'il est bon (à démontrer), il apparaît comme une patouille.
    Oui il fonctionne et si tu veux tu peux tester :
    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
     
    public class Main {
     
    	static interface ConstPersonne {
    		public String getNom();
    	}
     
    	static class Personne implements ConstPersonne {
    		private String nom;
    		public String getNom() {
    			return nom;
    		}
    		public void setNom(String nom) {
    			this.nom = nom;
    		}
    	}
     
    	@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);
    					}
    				});
    	}
     
    	public static void main(String[] args) throws Exception {
     
    		Personne personne = new Personne();
    		personne.setNom("azerty");
     
     
    		// Cas 1 : on utilise simplement une interface (même fonctionnalité que const)
    		ConstPersonne const1 = personne;
     
    		// La 'protection' peut être cassé avec un cast :
    		System.out.println( const1 instanceof Personne );	// affiche true
    		((Personne)const1).setNom("qwerty");			// OK (équivalent du const_cast)
     
     
     
    		// Cas 2 : on englobe l'instance dans un wrapper implémentant l'interface :
    		ConstPersonne const2 = wrapper(ConstPersonne.class, personne);
     
    		// La 'protection' ne peut être cassé avec un cast :
    		System.out.println( const2 instanceof Personne );	// affiche false
    		((Personne)const2).setNom("qwerty");			// KO : ClassCastException
     
    	}
    }
    Ce code permet d'empêcher le cast vers l'objet parent au runtime (donc d'empêcher l'équivalent du const_cast du C++) sans avoir à écrire la classe wrapper à la main...

    Mais j'avoue que je ne l'utilise pas les proxys pour cela (je me contente de l'interface).




    Mais tout cela est une affaire de contrat : si une méthode utilise un type spécifique elle ne doit normalement pas faire de cas particulier ou estimer qu'il s'agit d'un sous-type particulier (sauf bien sûr si c'est justement le rôle de la méthode). Tout comme une méthode C++ qui attend un const ne devrait pas utiliser const_cast...





    Citation Envoyé par grunt2000
    Il met en exergue la propreté et la commodité de const face à toutes les constructions plus ou moins complexes, plus ou moins solides, plus ou moins démontrées, qui voudraient remplacer son emploi.
    Comme je l'ai dit : pour avoir les mêmes possibilitées que le const il suffit d'utiliser une interface ou une classe parente ! Ce code sert seulement à empêcher les casts bêtes et méchants au runtime...



    Citation Envoyé par ®om
    Si le const était implémenté, il n'y aurait pas de "combine" pour le modifier...
    Ou alors il aurait fallut définir une interface "ReadOnlyCollection" dont hériterait l'interface Collection, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public interface ReadOnlyCollection {
    	int size();
    	boolean isEmpty();
    	boolean contains(Object o);
    	boolean containsAll(Collection<?> c);
    	Object[] toArray();
    	<T> T[] toArray(T[] a);
    }
    Cela permettrait d'avoir les erreurs à la compilation
    C'est plus lié à un défaut de conception qu'à l'absence du mot-clef const...


    Mais quoi qu'il en soit l'intégration du const, et surtout son utilisation dans les APIs standards, ajouterait trop de problème d'incompatibilité pour que ce soit envisagé...


    a++

  10. #50
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Je ne vois pas en quoi la méthode clone() n'a pas de sens sur un objet Immuable : on peut avoir 2 objets identiques (même modèle de téléphone avec le même répertoire, etc...) sans se partager le même objet. D'ailleurs cela empêcherait l'utilisation de prototypes ...


    En faite le vrai problème c'est de savoir si l'on veut un objet qui ne soit pas modifiable temporairement ? ou pour toute sa vie ?

    Dans le premier cas, il s'agit d'un problème d'autorité. Soit on utilise un verrou, soit on implémente Observer (pas nécessairement Listener).

    Dans le deuxième cas, il s'agit bien de l'instance d'une classe spécifique et on peut utiliser la magnifique Exception créée pour cela : UnsupportedOperationException (Voir le pattern Composant-Composé).


    Enfin une dernière question qu'il est bon de se poser : quel est le niveau de constance ? Si mon objet se compose d'une collection, est-ce que je peux ajouter ou retirer des éléments de celles-ci ? Est-ce ses éléments sont constants eux aussi ? Les mêmes questions se posent pour tout attribut non primitif...



    Mon avis est donc qu'un mot clé est inutile et que la solution sera différente pour chaque classe au sein d'un même système souhaitant utilisé ce principe.
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  11. #51
    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 Nemek
    Je ne vois pas en quoi la méthode clone() n'a pas de sens sur un objet Immuable : on peut avoir 2 objets identiques (même modèle de téléphone avec le même répertoire, etc...) sans se partager le même objet.
    Mais à quoi cela pourrait-il bien servir mis à part à consommer deux fois plus de mémoire ???

    Citation Envoyé par Nemek
    D'ailleurs cela empêcherait l'utilisation de prototypes ...
    C'est à dire ?


    Citation Envoyé par Nemek
    En faite le vrai problème c'est de savoir si l'on veut un objet qui ne soit pas modifiable temporairement ? ou pour toute sa vie ?
    Un objet immuable n'est pas modifiable pendant toutes sa vie...

    a++

  12. #52
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Ok j'avais pris l'utilisation du mot "const" comme quelque chose de temporaire... Dans ce cas, soit utilisé que des éléments primitifs finaux (y compris dans les classes en attribut), soit la solution que j'ai évoquée.


    La duplication d'un objet (ie un téléphone) permet à deux utilisateurs (ie toi et moi) de partager un objet sembable (ie téléphone de même modèle) mais distinct !

    Pardon, j'étais dans mon truc et j'ai oublié de dire que les "prototypes" sont issus d'un Pattern ("Prototype" ?) de fabrique qui consiste à stocker des instances et à les dupliquer pour les demandeurs.
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  13. #53
    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 Nemek
    Ok j'avais pris l'utilisation du mot "const" comme quelque chose de temporaire...
    const n'a pas du tout le même sens que l'immuabilité.
    const est bien "temporaire" et permet grosso-modo d'avoir une vue en lecture seule sur un objet muable.

    Citation Envoyé par Nemek
    La duplication d'un objet (ie un téléphone) permet à deux utilisateurs (ie toi et moi) de partager un objet sembable (ie téléphone de même modèle) mais distinct !
    C'est utile en effet lorsque l'objet peut être amener à évoluer pendant sa durée de vie, et que l'on ne souhaite pas qu'un utilisateur puisse modifier l'état de l'objet d'un autre utilisateur...

    Mais si l'objet est immuable il ne pourra pas du tout être modifié, et donc tous les utilisateurs peuvent se partager la même instance sans que cela ne pose de problème...

    a++

  14. #54
    Rédacteur/Modérateur
    Avatar de Logan Mauzaize
    Homme Profil pro
    Architecte technique
    Inscrit en
    Août 2005
    Messages
    2 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Transports

    Informations forums :
    Inscription : Août 2005
    Messages : 2 894
    Points : 7 083
    Points
    7 083
    Par défaut
    Effectivement dans ce cas-là, le clone() ne semble pas utile... Excepté si l'on a tendance à comparer les références pour des raisons x ou y. Exemple : un verrou ?

    Bon j'avoue un verrou avec des données ça peut sembler étrange. Mais s'il est porteur d'un contexte ça peut avoir du sens... Encore que un Singleton qui map le verrou avec son contexte résoudrait le problème.
    Mais je suis sûr qu'il doit bien exister un cas ou c'est nécessaire ....
    Java : Cours et tutoriels - FAQ - Java SE 8 API - Programmation concurrente
    Ceylon : Installation - Concepts de base - Typage - Appels et arguments

    ECM = Exemple(reproduit le problème) Complet (code compilable) Minimal (ne postez pas votre application !)
    Une solution vous convient ? N'oubliez pas le tag
    Signature par pitipoisson

  15. #55
    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
    Ah ouf la discussion revient on commençait à s'ennuyer !

    Moi non plus je ne vois pas trop à quoi le clone d'un objet constant pourrait servir...

    Puisqu'on aborde les diverses formes de <non>const c++</non><oui>immuables</oui>, voici un truc que j'avais trouvé interessant pour la culture générale : Implement a relaxed immutability model.
    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é.

  16. #56
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2007
    Messages
    340
    Détails du profil
    Informations personnelles :
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2007
    Messages : 340
    Points : 379
    Points
    379
    Par défaut
    Bonjour à tous, la discussion n'a pas été visitée depuis pas mal de temps mais c'est la première fois que je tombe dessus et en lisant ces pages j'ai pensé à un truc.

    Est-ce que quelque choses comme ceci ne ferait pas le travail du mot-clé const :

    1) d'abord une exception
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    public class ConstError extends Error {
     
        ...
     
    }
    2) ensuite une interface
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public interface Constantable {
     
        /** Renvoie "true" si l'objet est marqué "const" */
        void checkConst() thorws ConstError;
     
    }
    3) puis une classe construite avec un booléen

    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
     
    public class Person implements Constantable {
     
        private final boolean constant;
        private String name;
     
        public Person(String name, boolean constant) {
            this.constant = constant;
            this.name = name;
        }
     
        public void checkConst() {
            if (constant) throw new ConstError();
        }
     
        public void setName(String name) {
            checkConst(); // Si l'objet est marqué "const" une exception est levée.
            this.name = name; // sinon on continue le travail.
        }
     
    }
    Les problème qui me viennent ensuite à l'esprit sont les suivants :
    - il faut appeller checkConst() dans toutes les méthodes qui modifient les champs de l'objet.
    - il faut un booléen au constructeur de toutes les classes qui héritent de l'interface.
    - il faut réécrire toutes les classes écrites en java pour implémenter cette fonctionnalité.

    Pour résourdre le dernier point (oui on prend les choses à l'envers) il faudrait que se soit la classe object qui fournisse la méthode checkConst() mais bon si on parle d'extension du JDK c'est sun qui s'en charge donc pas de problème de ce côté... et on peut même passer la méthode en protected pour plus de propreté dans le code.

    Pour pallier au deuxième problème on pourrait apporter les modifications suivantes :

    (on implémentes ces fonctionnalités à la classe Object)
    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
     
        private int constFlag = 0;
     
        /** Définie l'état de constance de l'objet. */
        public void setConstState(int flag) throws ConstError {
            if (constFlag != 0) throw new ConstError(); // si on a déjà spécifié si l'objet est une constante ou pas
            switch (flag) {
            case 1 : constFlag = 1; break; // rend l'objet constant
            case 2 : constFlag = 2; break; // rend l'objet définitivement modifiable
            default : throw new ConstError(); // la valeur est mauvaise
            }
        }
     
        /** Vérifie si l'objet peut être modifié sinon lève une exception. */
        protected void checkConst() throws ConstError {
            if (constFlag == 1) throw new ConstError();
        }
     
    }
    Du coup pas besoin de booléen aux constructeurs de toutes les classes, il suffit d'appeller la méthode setConstState(int) pour définir l'état de l'objet, on peut même imaginer une syntaxe basée sur un mot clé permettant de faire ce travail de façon plus claire.

    Le dernier problème restant est que l'appel de checkConst() est nécessaire pour vérifier la validité des affectation de valeurs aux champs d'un objet. Le plus simple serait que la machine virtuelle effectue le travail seule, en appellant checConst() â chaque fois qu'une affectation à lieu mais ne sait pas si c'est implémentable ni quel peut en être le coup sur les performance.

    Je pense qu'une dernière difficulté se siturait là car si le comportement du mot clé const est défini il devrait pouvoir être gérer par le compilateur alors qu'avec ce type d'implémentation les test sont fait en temps réel donc ont un coup en temps de calcul pendant l'execution.

    Voilà c'était juste pour vous faire part des idées que cette discussion m'a évoqué.
    Bonne soirée, à bientôt.

  17. #57
    Expert éminent
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Points : 8 339
    Points
    8 339
    Par défaut
    Salut @ Tous !

    Je ne veux pas jeter du gas (comprenez de l'essence) sur un feu éteint...

    Mais simplement attirer votre attention sur le modifier "transient"
    => http://java.sun.com/docs/books/jls/t...s.html#8.3.1.3

    dont la sémantique correspond pour une certaine utilisation de const décrite dans la discussion.

    ceci à pour avantage de ne pas du tout overlapper sur final...
    Et peut-être dans certains cas, un ajout de sémantique sur transient permettrait d'obtenir la sémantique désirée pour const

    ++
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag (en bas)

Discussions similaires

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

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