Я пытаюсь обернуть голову в реализацию шаблона Стратегии в Java, так как считаю, что это реализация, которая необходима для получения желаемого поведения. У меня есть метод с именем chooseAction (), который принимает один параметр, который обозначает состояние мира в определенное время c. Допустим, он содержит информацию о текущем уровне трафика c и погоде, а также текущем времени. В зависимости от перечисления времени и списка доступных действий человека он может выполнять различные действия. Однако каждому действию нужен свой отдельный метод выбора, который возвращает логическое значение, обозначающее, будут ли они это делать. У Человека были бы другие причины выбирать, стоит ли ему go работать, чем bru sh свои зубы.
Это то, что у меня сейчас есть.
public enum Action{
GO_TO_WORK{
@Override
public TimeList getTimes() {
return new TimeList(Time.MORNING);
},
BRUSH_TEETH{
@Override
public Time getTimes() {
return new TimeList(Time.MORNING, Time.NIGHT);
},
WATCH_TV{
@Override
public Time getTimes() {
return new TimeList(Time.MORNING, Time.EVENING);
};
}
public class Person{
final static List<Action> availableActions; //Contains an unchanging list of actions a Person can do
public List<Action> chooseAction(WorldState worldState)
{
Time time = worldState.getTime(); //Get the current time
List<Action> validActions = getAvailableActions(time); //Actions the Person can do now
List<Action> chosenActions =
for (Action a : validActions) {
switch (a) {
case BRUSH_TEETH:
if (chooseToBrushTeeth(this, worldState))
chosenActions.add(a);
break;
case GO_TO_WORK:
if (chooseToGoToWork(this, worldState))
chosenActions.add(a);
break;
case WATCH_TV:
if (chooseToWatchTV(this, worldState))
chosenActions.add(a);
break;
default:
}
}
return chosenActions;
}
public List<Action> getAvailableActions(Time time)
{
List<Action> validActions = new ArrayList<>();
for(Action a: availableActions)
{
if(a.getTimes().contains(time))
{
validActions.add(a);
}
}
return validActions;
}
public enum Time{
MORNING, AFTERNOON, EVENING, NIGHT;
}
public class TimeList{
public TimeList(Time... time) {
for (Time t : times) {
this.add(t);
}
}
Индивидуальный выбор методы возвращают либо true, либо false в зависимости от параметров состояния Person и объекта WorldState. Точные спецификации этих методов и класса WorldState не имеют значения для этой проблемы. То, что я пытаюсь сделать, - это применить шаблон «Стратегия» или аналогичный шаблон проектирования, чтобы я мог удалить неэффективный переключатель / случай и большую часть избыточности. Сложность в том, что я не могу просто использовать наследование для создания разных объектов для каждого действия и заставить их вызывать свой собственный метод выбора. Это потому, что Действия не делают выбор, Человек делает. Я хочу спроектировать его так, чтобы, например, я мог иметь LazyPerson и ActivePerson, которые потенциально могут выбирать по-разному, когда GO_TO_WORK является допустимым действием, даже если WorldState одинаков.
Я думаю, что я близок к пониманию, но я еще не совсем там. Любая помощь будет принята с благодарностью.