Конструкция переключателя для комбинаций логических выражений

Предположим, у меня есть n логических значений, где n - относительно небольшое число (3-5 или около того). Допустим, что значения являются свойствами класса, каждое из которых может быть установлено или отключено независимо. Итак, есть 2n возможных комбинаций. Теперь я хочу различать эти комбинации по типу переключателя. В настоящее время я обычно делаю что-то вроде этого:

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
    ...
}

Это работает хорошо, но я не нахожу это очень элегантным. Есть ли лучшая практика (на Java) или идиома Java для подобных случаев?

1 ответ

Эта проблема является причиной, по которой они изобрели шаблон дизайна декоратора. Шаблон позволяет добавлять "черты" в ваш класс. Например, скажем, у вас есть класс Кофе. Каждый экземпляр кофе может быть с сахаром, молоком, сливками, подсластителем или взбитыми сливками (скажем, ни один из них не является взаимоисключающим). Таким образом, вместо пяти логических параметров (по одному для каждой характеристики кофе). У вас будет следующая иерархия:

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()));

Этот дизайн делает ваш код намного более читаемым и расширяемым, разделяя поведение каждого логического параметра на отдельный класс. Вызывающий напиток напечатает: "Yumm milk Yumm sugar Yumm coffee"

Другие вопросы по тегам