2014-11-28 8 views
5

Supponiamo di avere n valori booleani, dove n è un numero relativamente piccolo (3-5 circa). Diciamo che i valori sono proprietà di una classe, ognuna delle quali può essere impostata o disattivata indipendentemente. Quindi, ci sono 2 n combinazioni possibili. Ora voglio distinguere tra queste combinazioni in un modo simile a un interruttore. Attualmente, di solito faccio qualcosa del genere:Costruisci switch per combinazioni di booleani

int mask = (bool1 ? 1 : 0) + 
      (bool2 ? 2 : 0) + 
      (bool3 ? 4 : 0) + 
      ... ; 
switch (mask) { 
    case 0b000: 
     // all variables false 
    case 0b001: 
     // only bool1 true 
    case 0b011: 
     // only bool1 and bool2 true 
    ... 
} 

Questo funziona, ma non lo trovo molto elegante. C'è qualche best practice (in Java) o linguaggio Java per casi come questo?

+0

Perché non si usa se dichiarazione? Sarà molto più leggibile allora questo interruttore. – DontRelaX

+0

Questo ** potrebbe ** essere più adatto per [revisione del codice] (http://codereview.stackexchange.com/), sebbene non voti per chiudere in dubbio. – Mena

+0

@DontRelaX Ci sono alcuni modi per fare ifs, perché non metti il ​​tuo preferito come risposta. E considera come apparirà quando avrai 5 bool. – weston

risposta

0

Questo problema è il motivo per cui hanno inventato il Decorator Design Pattern. Il modello consente di aggiungere "tratti" alla tua classe. Per esempio diciamo che hai un caffè di classe. Ogni istanza di caffè può essere con zucchero, latte, crema, dolcificante o panna montata (diciamo che nessuno di questi si escludono a vicenda). Quindi, invece di avere cinque parametri booleani (uno per ogni tratto di caffè). Si avrà la seguente gerarchia:

public interface Coffee { 
    public void drink(); 
} 

public class CupOfCofee implements Coffee { 
    public void drink() { 
    print("Yumm coffee"); 
    } 
} 

abstract class CoffeeDecorator implements Coffee { 
    protected Coffee decoratedCoffee; 

    public CoffeeDecorator(Coffee decoratedCoffee) { 
    this.decoratedCoffee = decoratedCoffee; 
    } 

    public void drink() { 
    decoratedCoffee.drink(); 
    } 
} 

// We will provide coffee with sugar as an example. 
public class CoffeeWithSugarDecorator extends CoffeeDecorator { 
    public CoffeeWithSugarDecorator(Coffee decoratedCoffee) { 
    super(decoratedCoffee); 
    } 

    @Override 
    public void drink() { 
    print("Yumm sugar"); 
    super.drink(); 
    } 
} 

// Here is how you will initialize a coffee instance with sugar and milk. 
Coffee coffee = new CoffeeWithMilk(new CoffeeWithSugar(new CupOfCoffee())); 

Questo design rende il codice molto più leggibile ed estensibile separando i comportamenti di ciascun parametro booleano ad una classe separata. Chiamare bere stamperà: "Yumm latte Yumm zucchero Yumm caffè"

+0

Grazie per la risposta. Questo è un modello di design interessante, ma non penso che risolva completamente il problema. Innanzitutto, non è possibile specificare che alcuni codici debbano essere eseguiti se una decorazione è * non * presente. Secondo, se un 'Coffee' è decorato con' CoffeeWithMilk' e 'CoffeeWithSugar', viene eseguito il metodo' drink() 'di entrambe le decorazioni. Tuttavia, potrei voler eseguire il blocco di codice A se il latte è vero, il blocco di codice B se lo zucchero è vero, e il blocco C completamente indipendente se sia lo zucchero sia il latte sono veri. Lo fai se il modello di decoratore può essere adattato per supportare questo? – Hoopje

+0

Come per il codice per la decorazione non presente è possibile scrivere una classe CoffeeWithoutMilk. Quindi puoi scrivere qualcosa come il nuovo CoffeeWithoutMilk (nuovo CoffeeWithSugar (nuovo CupOfCoffee())); Potresti scrivere un'altra classe chiamata CoffeeWithSugarAndMilk che farà qualcosa di completamente diverso a CoffeeWithSugar e CoffeeWithMilk. L'unico problema è che gli utenti devono essere consapevoli di utilizzare questa classe e non creare un nuovo CoffeeWithMilk (nuovo CoffeeWithSugar (nuovo CupOfCoffee())); –