Конструкция переключателя для комбинаций логических выражений
Предположим, у меня есть 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"