29 votes

Refactorisation de la création d'un nombre variable de planètes en Java

Je dois affecter une quantité aléatoire d'objets dans ce programme, et actuellement la seule façon de le faire est quelque chose comme ceci:

     if (star.returnZones() == 1) {
        this.createPlanet(planet1, star);
    }
    else if (star.returnZones() == 2) {
        this.createPlanet(planet1, star);
        this.createPlanet(planet2, star);
    }
    else if (star.returnZones() == 3) {
        this.createPlanet(planet1, star);
        this.createPlanet(planet2, star);
        this.createPlanet(planet3, star);
    }
    else if (star.returnZones() == 4) {
        this.createPlanet(planet1, star);
        this.createPlanet(planet2, star);
        this.createPlanet(planet3, star);
        this.createPlanet(planet4, star);
    }
    else if (star.returnZones() == 5) {
        this.createPlanet(planet1, star);
        this.createPlanet(planet2, star);
        this.createPlanet(planet3, star);
        this.createPlanet(planet4, star);
        this.createPlanet(planet5, star);
    }
 

Je suis sûr que c'est une façon beaucoup plus efficace de le faire, où chacun fait quelque chose dans ce sens. J'utiliserai le terme asAbovePlus pour signifier tout ce qui précède, plus une chose.

 if (star.returnZones() == 1) {
    this.createPlanet(planet1, star);
}
else if (star.returnZones() == 2) {
    asAbovePlus
    this.createPlanet(planet2, star);
}
 

Existe-t-il un moyen de faire quelque chose comme ça en Java? Cela aiderait vraiment.

90voto

njzk2 Points 17085

Commencez par supprimer les doublons:

 int zones = star.returnZones();
if (zones >= 1) {
    createPlanet(planet1, star);
}
if (zones >= 2) {
    createPlanet(planet2, star);
}
...
 

Vous pouvez voir que dans l'exemple où zones == 2 , il exécute les 2 blocs, donc vous gardez la même fonctionnalité.

Ensuite, vous pouvez voir qu'il s'agit en fait d'une boucle. Commencez par mettre les planètes dans un tableau:

 Planet[] planets = new Planet[] {planet1, planet2, ...};
for (int i = 0; i < star.returnZones(); i++) {
    createPlanet(planets[i], star);
}
 

46voto

user000001 Points 12050

Ajoutez les objets de la planète à un tableau, puis vous pouvez écrire:

 Planet[] planets = {planet1, planet2, planet3, planet4, planet5};

for (int i = 0; i < star.returnZones(); i++) {
    this.createPlanet(planets[i], star);
}
 

44voto

Holger Points 13789

Une façon de le faire, est une switch déclaration en automne, par le comportement:

switch (star.returnZones()) {
    case 5: this.createPlanet(planet5, star); // fall-through
    case 4: this.createPlanet(planet4, star); // fall-through
    case 3: this.createPlanet(planet3, star); // fall-through
    case 2: this.createPlanet(planet2, star); // fall-through
    case 1: this.createPlanet(planet1, star); // fall-through
}

Depuis la chute-à travers le comportement est réalisé en l'absence d'un break déclaration, il est fortement recommandé d'ajouter de la clarification des commentaires, comme indiqué ci-dessus, afin que le lecteur comprend tout de suite que le manque break des déclarations sont intentionnels.

Un inconvénient est qu'il va créer les planètes dans l'ordre inverse.

Une alternative est une boucle:

Planet[] planet={ planet1, planet2, planet3, planet4, planet5 };
int number = star.returnZones();
if(number>0 && number<=5) {
    for(int pIndex=0; pIndex<number; pIndex++)
        this.createPlanet(planet[pIndex], star);
}

Notez que dans les deux cas, vous devriez penser à ce qui devrait se produire avec des valeurs en dehors de la plage. Si vous supposez que cela n'arrivera jamais, vous devez ajouter un code qui renvoie une erreur, si l'hypothèse est violée, pour s'assurer que l'incohérence ou des données corrompues est immédiatement détectée au lieu de continuer avec ce que l'utilisateur peut signaler comme "comportement étrange" (sans avoir la moindre idée sur la véritable source du problème), par exemple

switch (star.returnZones()) {
    default: throw new AssertionError("returnZones should be 1..5");
    case 5: this.createPlanet(planet5, star); // fall-through
    case 4: this.createPlanet(planet4, star); // fall-through
    case 3: this.createPlanet(planet3, star); // fall-through
    case 2: this.createPlanet(planet2, star); // fall-through
    case 1: this.createPlanet(planet1, star); // fall-through
}

ou

Planet[] planet={ planet1, planet2, planet3, planet4, planet5 };
int number = star.returnZones();
if(number>0 && number<=5) {
    for(int pIndex=0; pIndex<number; pIndex++)
        this.createPlanet(planet[pIndex], star);
}
else throw new AssertionError("returnZones should be 1..5");

10voto

pulp_fiction Points 10

Vous pouvez également avoir une méthode statique prenant des varags appelés createPlanets(PlanetCreator creator, Star star, Planet...planets) .

Et puis tout ce que vous aurez à faire est de passer vos planètes sous forme de tableau ou séparées par des virgules (toujours tableau finalement) et de les parcourir:

 public static void createPlanets(PlanetCreator creator, Star star, Planet...planets) {
    for (Planet p: planets) {
        creator.createPlanet(p, star);
    }
}
 

10voto

Timothy Truckle Points 8408

Il existe une autre solution similaire à la première partie de la réponse de @ njzk2: c'est switch/case avec chute :

 int zones = star.returnZones();
switch (zones ) {
 case 5:
    createPlanet(planet5, star);
 case 4:
    createPlanet(planet4, star);
 case 3:
    createPlanet(planet3, star);
 case 2:
    createPlanet(planet2, star);
 default:
    createPlanet(planet1, star);   
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X