#design-patterns #code-cleanup
Вопрос:
Конечно, когда мы говорим о количестве «если», мы стараемся использовать шаблон Стратегии. Но как насчет того, когда я хочу разделить условия внутри if().
Например, я разрабатываю игру со многими возможностями:
У меня есть занятие под названием «Игра». Я проверяю метод и возвращаю перечисление.
if(TieByPoints()) {
return Result.TieByPoints;
}
if(TieByTimeOver()) {
return Result.TieByTimeOver;
}
if(JustOnePlayerWin()) {
return Result.PlayerWin;
}
if(ManyPlayersWin()) {
return Result.PlayerWin;
}
Но можно создать множество других возможностей/правил.
Итак, есть ли способ разделиться на разные классы? Поставить эти условия в разных местах?
Комментарии:
1. В чем проблема, которую вы пытаетесь решить, или запах кода, который вы хотите устранить? Это поможет, если вы сможете объяснить, что вам не нравится в этом коде.
2. Если появятся новые правила, я должен буду создать новые условия if. Итак, есть ли способ избежать этого?
Ответ №1:
Вы не объяснили достаточно подробностей, чтобы сказать с уверенностью, но одним из подходов было бы использование шаблона реестра, в котором в реестре хранятся производители результатов.
Что-то вроде
public enum Result { None, TieByPoints, ... };
public class ResultSupplierRegistry {
/** Singleton instance of registry. */
public static final ResultProducerRegistry INSTANCE = new ResultSupplierRegistry();
private final Map<Result, Supplier<Boolean>> resultSuppliers = new HashSet<>();
private ResultSupplierRegistry() {}
public void register(Result result, Supplier<Boolean> resultSupplier) {
resultSuppliers.put(result, resultSupplier);
}
public Result getResult() {
return resultSuppliers.entrySet().stream().filter(e -> e.getValue().get()).map(Entry::getKey).findFirst().orElse(Result.None);
}
}
Теперь вам нужна некоторая инициализация для заполнения реестра. Я не принял здесь никаких мер предосторожности по безопасности потоков. Если инициализация может выполняться несколькими потоками, вам нужно будет это исправить.
Комментарии:
1. Отлично! Я никогда об этом не думал. Спасибо.