Quels sont les moyens d’éliminer l’utilisation du commutateur dans le code ?
Réponses
Trop de publicités?Commutateur-déclarations ne sont pas un antipattern en soi, mais si vous utilisez le codage orienté objet vous devriez considérer si l’utilisation d’un interrupteur est mieux résolue avec polymorphisme au lieu d’utiliser une instruction switch.
Avec polymorphisme, ceci :
devient ceci :
Voir les Instructions de commutation Odeur:
Généralement, semblable instructions de commutation sont dispersés tout au long d'un programme. Si vous ajoutez ou supprimez une clause dans un commutateur, vous avez souvent à trouver et réparer les autres aussi.
Les deux Refactoring et Refactoring de Modèles ont des approches pour résoudre ce problème.
Si votre (pseudo -) code ressemble à ceci:
class RequestHandler {
public void handleRequest(int action) {
switch(action) {
case LOGIN:
doLogin();
break;
case LOGOUT:
doLogout();
break;
case QUERY:
doQuery();
break;
}
}
}
Ce code viole le Principe Ouvert Fermé et est fragile à chaque nouveau type de code d'une action qui vient. Pour remédier à cela, vous pouvez introduire une 'Commande' objet:
interface Command {
public void execute();
}
class LoginCommand implements Command {
public void execute() {
// do what doLogin() used to do
}
}
class RequestHandler {
private Map<Integer, Command> commandMap; // injected in, or obtained from a factory
public void handleRequest(int action) {
Command command = commandMap.get(action);
command.execute();
}
}
Si votre (pseudo -) code ressemble à ceci:
class House {
private int state;
public void enter() {
switch (state) {
case INSIDE:
throw new Exception("Cannot enter. Already inside");
case OUTSIDE:
state = INSIDE;
...
break;
}
}
public void exit() {
switch (state) {
case INSIDE:
state = OUTSIDE;
...
break;
case OUTSIDE:
throw new Exception("Cannot leave. Already outside");
}
}
Ensuite, vous pouvez introduire un "État" de l'objet.
abstract class HouseState {
public HouseState enter() {
throw new Exception("Cannot enter");
}
public HouseState leave() {
throw new Exception("Cannot leave");
}
}
class Inside extends HouseState {
public HouseState leave() {
return new Outside();
}
}
class Outside extends HouseState {
public HouseState enter() {
return new Inside();
}
}
class House {
private HouseState state;
public void enter() {
this.state = this.state.enter();
}
public void leave() {
this.state = this.state.leave();
}
}
Espérons que cette aide.
Un commutateur est un modèle, que mis en œuvre avec une instruction switch, si le reste de la chaîne, table de recherche, programmation orientée objet, le polymorphisme, la correspondance de motif ou quelque chose d'autre.
Voulez-vous éliminer l'utilisation de la "switch" ou le "commutateur de modèle"? Le premier peut être éliminé, le second, seulement si un autre motif/algorithme peut être utilisé, et la plupart du temps ce n'est pas possible ou c'est pas la meilleure approche pour le faire.
Si vous voulez éliminer l' instruction switch à partir du code, la première question à se poser est où est-il judicieux d'éliminer l'instruction switch et l'utilisation d'une autre technique. Malheureusement, la réponse à cette question est spécifique au domaine.
Et n'oubliez pas que les compilateurs peuvent faire diverses optimisations pour les instructions switch. Ainsi, par exemple, si vous voulez faire du traitement d'un message de manière efficace, une instruction switch est à peu près le chemin à parcourir. Mais d'autre part, l'exécution de règles de gestion basées sur une instruction switch est probablement pas la meilleure façon d'aller et la demande doit être rearchitected.
Voici quelques solutions de rechange à l'instruction switch :
- table de recherche
- le polymorphisme
- le pattern matching (surtout utilisé en programmation fonctionnelle, les modèles C++)
Interrupteur en soi n’est pas mauvais, mais si vous avez beaucoup de « switch » ou « if/else » sur les objets dans vos méthodes, il peut être un signe que votre conception est un peu « procédurale » et que vos objets sont juste des seaux de valeur. Transférer la logique à vos objets, appeler une méthode sur vos objets et laissez-les décider comment répondre à la place.