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 :

Objet java en "Lecture seule"


Sujet :

Langage Java

  1. #1
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Avril 2005
    Messages
    277
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39

    Informations forums :
    Inscription : Avril 2005
    Messages : 277
    Par défaut Objet java en "Lecture seule"
    Bonjour,

    Je souhaiterais juste avoir si il est possible de rendre un objet JAVA en "Lecture seule" pour un temps donné ...

    Je détaille ... J'ai un objet que j'ai créé ... Parfois je le passe en paramètre dans des méthodes ... Il peut arriver que je ne veuille pas qu'il soit modifiable par certaines méthodes ... Y a t'il un moyen de faire ca ?

    Le pourquoi est le fait de protèger le programme des erreurs de code ...
    genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public void maMethode( monObjet _obj )
    {
      monObjet objetA = _obj;
      objetA.maValeur = 2;
    }
    Cela arrive dans les grosses boucles ... Et la méthode clone() n'est pas toujours présente !!! Et cloner un objet alors qu'a cet endroit il doit être uniquement LU, ca le fait moyen je trouve niveau perfs ...

    Je ne pense pas que ca soit possible, mais peut être que si ...

    J'ai regardé ce qui est "immuable" mais ca ne correspond pas à ma demande ...

    Merci à vous !

  2. #2
    Membre expérimenté Avatar de welcome_59
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mars 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2007
    Messages : 203
    Par défaut
    En effet la solution n'est pas dans le concept d'immuabilité. Essaie par les Threads et la synchronisation.

  3. #3
    Membre éprouvé Avatar de reno_tidus
    Profil pro
    Inscrit en
    Août 2007
    Messages
    132
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 132
    Par défaut
    déclare ton paramètre comme final, la méthode ne pourra ainsi pas le modifier

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public void maMethode( final monObjet _obj) {
      
    }

  4. #4
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Avril 2005
    Messages
    277
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39

    Informations forums :
    Inscription : Avril 2005
    Messages : 277
    Par défaut
    Merci mais pour le
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public void maMethode( final monObjet _obj) {
     
    }
    On ne peux pas modifier _obj même par un new nomObjet(...), mais on peu modifier les variables contenues dans l'objet par un _obj.maValeur = 2;

    Malheureusement ... J'avais testé ...

  5. #5
    Membre Expert Avatar de herve91
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    1 282
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 282
    Par défaut
    Il n'y a pas de solution simple à ton problème, dans la mesure où le mot clef const, même si je crois qu'il est réservé, n'est pas traité par le compilateur Java. Il me semble d'ailleurs qu'il y a eu une discussion ici à ce sujet.
    Une possibilité, qui nécessite quand même pas mal de modifications, est de définir une interface pour chacune des classes que tu veux rendre temporairement "en lecture seule". Un exemple permettra de comprendre ce concept.
    Tu disposes de la classe suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Personne {
      private String nom;
     
      public String getNom() {
        return nom;
      }
     
      public void setNom(String nom) {
        this.nom  = nom;
      }
    }
    et de son utilisation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void maMethode(Personne personne) {
      personne.setNom(null); // ici l'accès en écriture devrait être interdit
      ...
    }
    Tu définis alors l'interface suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    interface IPersonne {
      String getNom();
    }
    et tu modifies la classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    class Personne implements IPersonne {
    ...
    L'utilisation devient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void maMethode(IPersonne personne) {
      personne.setNom(null); // maintenant ça ne compile plus !
      ...
    }
    Bien sûr une personne mal intentionnée pourra toujours faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void maMethode(IPersonne personne) {
      ((Personne) personne).setNom(null); // ça compile à nouveau !
      ...
    }
    En jouant sur la visiblité de la classe Personne, tu peux par exemple faire en sorte qu'elle ne soit pas accessible en dehors du package où elle est définie, ce qui peut être rédhibitoire car dans ce cas on ne peut plus hériter de la classe Personne en dehors de son package de définition...

  6. #6
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2007
    Messages
    697
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 697
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public void maMethode( monObjet _obj )
    {
      monObjet objetA = _obj;
      objetA.maValeur = 2;
    }
    Java est un langage objet (les nom de classe commence par une Majuscule) et donc normalement pour modifier un objet, on passe par un accesseur. Donc pas de ObjetA.maValeur = 2; mais
    tu dois créer des accesseur pour ton objet :

    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
    public class ObjetA{
        private int maValeur;
        private boolean accessible = true;
        public ObjetA(int value){
            this.maValeur = value;
        }
        public void setAccessible(boolean b){
            this.accessible = b;
        }
     
        public void setMaValeur(int v){
        if(accessible){
            this.maValeur = v;
        }
    }
    Ainsi si tu veut interdire l’accès à ton objet tu mets la variable accessible à false.

  7. #7
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    361
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 361
    Par défaut
    Citation Envoyé par reno_tidus Voir le message
    déclare ton paramètre comme final, la méthode ne pourra ainsi pas le modifier
    C'est faux. Ca n'empêchera pas du tout la modification de l'objet.
    Ca intedit juste d'affecter une variable au paramètre.

  8. #8
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2007
    Messages
    697
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Janvier 2007
    Messages : 697
    Par défaut
    oui mais un objet est definie par ses variable et ses methodes donc si toutes les variables sont sécurisé ainsi alors on ne modifie pas l'objet

  9. #9
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Avril 2005
    Messages
    277
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39

    Informations forums :
    Inscription : Avril 2005
    Messages : 277
    Par défaut
    Oui excuse moi pour l'obli de la majuscule a mon nom de classe ... lol

    Sinon je suis d'accord avec vous, mais mon soucis est que je veux dans certains cas MODIFIER, dans certains cas LIRE ! et ce pour le même objet !!!

    Exemple de 2 méthodes dans une même classe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public void maMethodeModifie( MonObjet _obj )
    {
      MonObjet objetA = _obj;
      // ici j'ai le droit de modifier
      objetA.maValeur = 2;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public void maMethodeLit( MonObjet _obj )
    {
      MonObjet objetA = _obj;
      // ici je n'ai pas le droit de modifier 'objetA'
      // je voudrais donc que la ligne qui suit soit impossible
      objetA.maValeur = 2;
    }
    Je rapelle que cette interdiction serait juste établie par MOI, juste afin de protèger des objets d'éventuelles modifications dans des endroits ou ils ne sont que LUS ...

    Petit plus : Vous pourriez me dire "Apprends à développer et tout ira bien" mais dans des grosses applis on n'est jamais à l'abri d'étourderies ... Puis je suis pas un pro du JAVA, loin de la ! J'apprends avec le temps et avec developpez ^^ Et enfin je vais pas être seul sur les projets, et les autres vont commencer JAVA ...
    -> Voila pourquoi je cherche à faire ça !

    Merci encore ^^

  10. #10
    Membre expérimenté Avatar de xv-mnt
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juillet 2005
    Messages : 142
    Par défaut
    Tu peux aussi passer une copie de l'objet que tu veux immuable comme paramètre de la méthode appelée, charge à toi de rendre ton objet Clonable.
    Comme celà, tu es sûr que ton objet ne sera pas modifié.
    Sinon, tu peux limiter la portée de tes accesseurs setXXX() à private, protected, ou default, et non public, ce qui limiterait déjà pas mal les cas de modifications intempestives.

    Pour plus d'information, il existe un livre en anglais (peut-être est-il traduit) : "Effective Java" de Joshua Bloch chez Addisson Wesley et voir les Items 12, 13, 24, 56 pour traiter des données immutables, ou bien réaliser des copies "défensives".

  11. #11
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par JamesP Voir le message
    Sinon je suis d'accord avec vous, mais mon soucis est que je veux dans certains cas MODIFIER, dans certains cas LIRE ! et ce pour le même objet !!!
    La solution t'a été donné par herve91 : utilise des accesseurs et une interface).


    a++

    PS : je trouve les textes en violet particulièrement illisible sur le fond du forum...

  12. #12
    Membre éclairé
    Homme Profil pro
    Inscrit en
    Avril 2005
    Messages
    277
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39

    Informations forums :
    Inscription : Avril 2005
    Messages : 277
    Par défaut
    Oki désole pour le violet alors ...

    Sinon j'ai bien lu la réponse de hervé91 !

    Ca empêche à quelqu'un d'utiliser des setteur (par exemple) dans une classe ...

    Mais je ne vois pas où cela bloque les modifications d'un objet juste pour une méthode d'une classe qui prends en paramètre cet objet !

    Peut être que j'ai mal compris ...

  13. #13
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    361
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 361
    Par défaut
    Citation Envoyé par atha2 Voir le message
    oui mais un objet est definie par ses variable et ses methodes donc si toutes les variables sont sécurisé ainsi alors on ne modifie pas l'objet
    Je n'ai jamais dit le contraire, je citais reno_tidus.

  14. #14
    Membre chevronné Avatar de bassim
    Homme Profil pro
    Ingénieur Réseaux
    Inscrit en
    Février 2005
    Messages
    666
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur Réseaux
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2005
    Messages : 666
    Par défaut
    pourquoi ne pas utiliser le pattern Etat qui selon l'état de l'objet tu peux restreindre la modification des ses paramètres

  15. #15
    Membre éprouvé
    Avatar de mavina
    Homme Profil pro
    Développeur Java
    Inscrit en
    Octobre 2004
    Messages
    1 812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2004
    Messages : 1 812
    Par défaut
    Salut,

    Sinon dans les solutions toutes bêtes, une fonction "principale" qui redirige vers deux fonctions privées annexes.

    Exemple :

    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
     
    public void maFonctionQuiModifieLObjetOuPas(Obj o)
    {
        if (casOuOnModifie == true)
           maFonctionQuiModifieLObjet(o);
        if (casOuOnNeModifiePas == true)
           maFonctionQuiNeModifiePasLObjet(o);
    }
     
    private void maFonctionQuiModifieLObjet(Obj o)
    {
    (...)
    }
     
    private void maFonctionQuiNeModifiePasLObjet(Obj o)
    {
    (...)
    }
    Simple, efficace.
    Ya surement mieux mais c'est la premiere chose qui me vienne à l'esprit.

    Citation Envoyé par atha2 Voir le message
    oui mais un objet est definie par ses variable et ses methodes donc si toutes les variables sont sécurisé ainsi alors on ne modifie pas l'objet
    Euh, j'ai peut-être pas bien compris ce que tu voulais dire, mais déclarer un paramètre final empeche juste de référencer un autre objet avec la référence du paramètre. En clair, ton parametre x en final, rien ne t'empeche d' appeler dessus un setter ou une fonction qui va le modifier de l'intérieur...

    Fred

  16. #16
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par JamesP Voir le message
    Mais je ne vois pas où cela bloque les modifications d'un objet juste pour une méthode d'une classe qui prends en paramètre cet objet !
    Ben si cette méthode prend en paramètre une interface qui ne défini pas de setter elle ne pourra pas modifier l'objet (à moins de faire un cast crade, et encore il y a moyen de s'en protéger avec un type wrapper).

    a++

  17. #17
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Février 2007
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Février 2007
    Messages : 80
    Par défaut
    Bonjour,

    Citation Envoyé par adiGuba
    Ben si cette méthode prend en paramètre une interface qui ne défini pas de setter elle ne pourra pas modifier l'objet (à moins de faire un cast crade, et encore il y a moyen de s'en protéger avec un type wrapper)
    Le cast crade, c'est celui dont parle hervé91:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void maMethode(IPersonne personne) {
      ((Personne) personne).setNom(null); // ça compile à nouveau !
      ...
    }
    Mais je comprends pas quand tu dis qu'on peut s'en protéger avec un type wrapper ? Comment on peut bloquer ce cast ?

    Philippe.

  18. #18
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par pverley Voir le message
    Mais je comprends pas quand tu dis qu'on peut s'en protéger avec un type wrapper ? Comment on peut bloquer ce cast ?
    Avec un type "wrapper", c'est à dire un type qui se contente d'encapsuler un autre type. Par exemple pour continuer sur le code d'herve91 :

    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
    class PersonneWrapper implements IPersonne {
      /** Reference vers le type contenu */
      private final IPersonne inner;
     
      /** Constructeur de base */
      public PersonneWrapper(IPersonne personne) {
          this.inner = personne;
      }
     
      /** Implémentation de l'interface (renvoi vers le type contenu) */
      public String getNom() {
          return this.inner.getNom();
      }
     
    }
    Ainsi si tu veux vraiment être sûr que la méthode ne fera pas de cast, il suffit de faire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Personne personne = ...;
    maMethode(new PersonneWrapper(personne));
    Et le cast provoquera un ClassCastException

    a++

  19. #19
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Février 2007
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Février 2007
    Messages : 80
    Par défaut
    Ok, merci adiGuba, j'ai fais des essais et je comprends maintenant.

    On comprend vraiment la nature tout objet du java avec cette exemple : une classe, une interface et un wrapper pour manipuler proprement l'objet Personne !

    Cette construction est propre, est-elle couteuse ? Si je comprends bien, quand on fait new PersonneWrapper(personne), on crée une nouvelle référence mais l'objet personne n'est pas dupliqué en mémoire ? Donc à priori pas de problème

    Dernière question, si on développe plusieurs classes de cette façon (la classe, l'interface pour les getters, et le wrapper pour prévenir les cast crapuleux) on finit vite envahi de fichiers ... comment tu structures ? Tu déclares l'interface IPersonne dans Personne.java, par exemple, et le wrapper à côté ? Ou tu fais des sous packages qui regroupent toutes les interfaces de getters et tous les wrappers ?

    Encore merci,
    A +

  20. #20
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par pverley Voir le message
    Cette construction est propre, est-elle couteuse ? Si je comprends bien, quand on fait new PersonneWrapper(personne), on crée une nouvelle référence mais l'objet personne n'est pas dupliqué en mémoire ? Donc à priori pas de problème
    Il y a juste le coût de la création d'un nouvel objet. Et à la rigueur il faut essayer de la conserver si on veut la réutiliser...

    Citation Envoyé par pverley Voir le message
    Tu déclares l'interface IPersonne dans Personne.java, par exemple, et le wrapper à côté ? Ou tu fais des sous packages qui regroupent toutes les interfaces de getters et tous les wrappers ?
    Non : chaque classe/interface dans son propre fichier.
    Si tu met l'interface dans "Personne.java" alors tu ne peux pas la déclarer "public" mais "package-only" et elle ne sera visible que par les classes du même packages

    Perso j'utilise toujours un fichier par type, sauf dans quelques cas particulier :
    • Le type n'est utilisé que dans une seule classe il peut alors être déclaré dans son fichier source.
    • Le type est intimement lié à un autre type, alors cela peut carrément être un type interne (exemple : une enum correspondante aux valeurs d'une des méthodes de la classe).
    • Le type a des rapports particuliers avec un autre type ==> type interne afin de bénéficier d'accès privilégier a ses données.
    • etc...


    Mais je ne regroupe en aucun cas les classes simplement pour avoir "moins de fichiers"...


    Sinon perso je n'utilise pas vraiment de wrapper (en tout cas pas dans ce cas précis) : Les méthodes qui manipule une interface n'utilisent que les méthodes de cette interface et ne cherchent pas à faire de tel cast... sauf dans le cas particulier des interfaces marqueurs décrivant un comportement (Closeable, Serializable, Comparable, etc...).


    a++

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 2
    Dernier message: 30/03/2007, 21h11
  2. [Access 2003]- erreur 3027 : base ou objet en lecture seule
    Par metallica_fr dans le forum Access
    Réponses: 5
    Dernier message: 15/12/2006, 17h36
  3. Mise à jour impossible, objet en lecture seule
    Par Pitou5464 dans le forum Access
    Réponses: 3
    Dernier message: 12/09/2006, 18h26
  4. Base de Données ou objet en lecture seule?
    Par ben_skywalker dans le forum Access
    Réponses: 6
    Dernier message: 01/06/2006, 08h47

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