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 :

Restreindre méthodes accessibles


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 17
    Par défaut Restreindre méthodes accessibles
    Bonjour,

    J'ai un petit soucis dans un programme perso (jeu avec des bateaux )...
    Alors voila pour faire simple, j'ai une classe Fleet ("Flotte" pour les puritains) qui a des getteurs et setteurs. exemple:
    *getCoordonnees
    *setCoordonnees

    Cette classe est utilisé a plusieurs endroit du programme, notamment :
    * Le "GameBoard" qui est le cerveau du jeu et connait en permanence l'état actuel du jeu et donc les Flottes existantes.
    * Les classes implémentant l'interface "Bot" qui représentent les différents bots que je suis en train de créer pour l'IA.

    Le jeu est plutôt destiné à des dev., le but étant de proposer à chacun de développer son propre Bot et de se mesurer à d'autres IA.

    Voilà pour l'intro =)

    Le problème :

    Dans la fonction principale d'un Bot, on récupère un objet gameboard et on retourne un ensemble de flottes représentant les nouvelles flottes à envoyer.
    Il faut donc pouvoir créer un objet Flotte (=> Flotte != interface), mais on ne doit pas pouvoir utiliser de setter, au risque de pouvoir modifier les données contenues dans le gameboard (par exemple, "téléporter" une flotte à l'endroit souhaité...).

    Dans le gameboard, on doit manipuler des objets flottes et mettre à jour leurs coordonnées au fur et à mesure du jeu (à chaque tour, elle avance), ainsi, le moteur graphique peut ensuite afficher la flotte à ses nouvelles coordonnées.


    Question :
    Quelle serait la bonne façon de faire pour limiter l’accès aux setters ?

    Pour info ce que j'ai fait :
    Pour l'instant, je cast les Flottes retourné par le bot en FlotteImpl qui est une classe fille qui dispose de setters (Flottes n'en a pas). à Chaque tour je doit regenerer une list<Flotte> a partir de ma list<FlotteImpl>, je trouve ça assez lourd.


    Merci =)

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Avril 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 17
    Par défaut
    Je pensais, peut être que si je créé une Factory qui me retourne des objets Fleets ca marcherai ?

    Ainsi je n'aurais plus le problème "Fleet != interface" et je pourrai clairement expliciter les méthodes accessibles.

    Qu'en pensez-vous ?

    PS : une factory nommée "ChantierNaval" ou "Brest"

  3. #3
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Salut,

    Selon ce modèle (faire une interface avec que le getter, et créer des objets avec un accesseur non public, mais quand même accessible par d'autres classes, donc à priori default, ou protected), il est facile de créer une classe dans le package (même si tu as fait un jar de tes classes), qui permet de muter l'objet (si tu fournis un moyen d'en obtenir la référence à l'extérieur).

    Dans tes classes (donc au final dans ton jar)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    package truc; 
    public interface IFleet {
     XY get();  // uniquement un getter dans l'interface
    }
    L'implementation concrète avec ta méthode de mutation (que tu penses n'être accessible que dans ton package, ou ton arbo de classes, si protected), que tu l'instancies par fabrique ou pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    package truc; 
    public class Fleet implements IFleet {
     
       void set(XY n) { // portée default
           ...
       }
     
       ...
     
    }
    On peut faire, dans un autre jar :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    package truc; 
    public class FleetTeleport {
     
       public static void set(Fleet fleet, XY n) {
           fleet.set(n); // même package donc visible
       }
     
    }
    et ensuite dans n'importe classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public static void teleporte(Fleet fleet, XY n) {
        truc.FleetTeleport.set(fleet, n);
    }
    Seule la portée private empêchera de muter de l'extérieur.


    Si tes coordonnées doivent être mutées uniquement par ton gameboard, stockes les dans ton gameboard : utilises une classe interne avec mutateur de portée private , qui implémente ton interface IFleet
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  4. #4
    Rédacteur
    Avatar de bulbo
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2004
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Février 2004
    Messages : 1 259
    Par défaut
    Pour avoir déjà écrit ce genre de moteurs je te conseillerais plutôt de fournir aux IAs un clone du plateau de jeu et tu les laisses faire ce qu'elles veulent avec.
    Tu ne t'embêtes pas à restreindre les setters, elles auront chacune leur copie et pourront l'utiliser directement pour établir leur stratégie propre.
    Ton Moteur de jeu par contre n'acceptera de modifications de son plateau que par le biais de méthode de jeu dédiée.

    Mes 2 cents,

    Bulbo
    [Java] [NetBeans] [CVS]
    La FAQ Java
    Merci de ne pas me poser de questions techniques par MP.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Avril 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 17
    Par défaut
    Merci pour vos réponses !

    @bulbo, c'est a peu près ce que je faisait, mais la création d'une copie exigeant un certain temps d’exécution, je pensais pouvoir faire mieux.

    @joel, donc en gros je fais une truc du genre :


    Pour le bot (accessible aux participants)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    package public;
    public class Bot1 extends Bot {
     
        public List<Fleet> jouer(Gameboard game) {
            List<Fleet> fleetToSend = new ArrayList();
     
            // reflexion du bot [...]
     
            fleetToSend.add(new Fleet(ileDepart, IleCible, ...));
            return fleetToSend;
        }
    }
    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
     
    package public.ressources;
    public class Fleet {
     
        private XY coordonees;
     
        public Fleet(Ile ileDepart, Ile ileCible, ...) {
            // contructeur
        }
     
        public XY getCoordonnees() {
            // getteur accessible pour Bot
        }
     
        // autres getteurs ...
     
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    package public.ressources;
    public interface GameBoard {
     
        // tous les getteurs accessibles au joueur
        // exemple :
     
        /**
         * @return la liste des flottes existantes
         */
        List<Fleet> getFleets();
    }
    pour le coté moteur de jeu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    package admin;
    import public.ressources.Fleet;
     
    public class FleetImpl extends Fleet {
     
        // pas de nouveaux attributs, constructeur identique
     
        protected setCoordonnees(XY newCoord) {
            // ...
        }
     
        // autres setteurs si necessaire
    }
    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
     
    package admin;
     
    // import pas beau mais c'est pour expliquer =)
    import public.ressources.*;
     
    public class GameBoardImpl implements GameBoard {
     
        private List<FleetImpl> fleets = new ArrayList();
        private Bot bot1;
        // autres attributs
     
        // Constructeur
        // getteurs et setteur
     
        public void jouerbot() {
            // ...
            List<Fleet> toAdd = bot1.jouer(this);
            for (Fleet f : toAdd) {
                // controle de f ...
                fleets.add((FleetImpl)f);
            }
            // ...
        }
     
        public void moveFleets() {
            //...
            for (FleetImpl f : fleets) {
                //...
                // possible car FleetImpl et GameBoardImpl dans le même package "admin"
                // et setCoordonnees est protected
                f.setCoordonnees(newXY);
                //...
            }
            //...
        }
     
        @override
        public List<Fleet> getFleets() {
            // ????????
            // impossible de caster FleetImpl en Fleet (classe mère)
        }
    }
    Voilà j'ai toujours ce même problème... à moins que je n'ai pas bien saisi ton idée joel ?

    Merci encore pour votre aide !

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Avril 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 17
    Par défaut
    Pardon, je crois avoir compris ton idée de package pour limiter la portée via le mot-clé protected.

    Le problème c'est que les classes utiles au joueur doivent être dans un package entièrement public...
    Au moment de commencer le jeu ils auront ce package (non modifiable mais javadoc consultable) et un exécutable qui prendra en paramètre le nom de leur bot.
    Ainsi je masque toutes les autres classes afin qu'il ne puisse pas les analyser dans la recherche de bugs/failles exploitables, ni carrement les utiliser pour tricher.


Discussions similaires

  1. Réponses: 7
    Dernier message: 20/12/2007, 12h37
  2. Restreindre la visibilité d'une méthode
    Par Bicnic dans le forum Langage
    Réponses: 5
    Dernier message: 26/05/2006, 21h45
  3. Réponses: 3
    Dernier message: 13/04/2006, 17h35
  4. Réponses: 2
    Dernier message: 05/01/2006, 15h17
  5. Réponses: 2
    Dernier message: 18/11/2005, 17h29

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