Я столкнулся с проблемой при использовании шаблона стратегии. Я использую службу для создания задач. Эта услуга также решает ответственного клерка для выполнения этой задачи. Решение клерка выполняется с использованием шаблона стратегии, потому что есть разные способы сделать это. Дело в том, что каждая стратегия может потребовать разных параметров для решения клерка.Шаблон стратегии с различными параметрами
Например:
interface ClerkResolver {
String resolveClerk(String department);
}
class DefaultClerkResolver implements ClerkResolver {
public String resolveClerk(String department) {
// some stuff
}
}
class CountryClerkResolver implements ClerkResolver {
public String resolveClerk(String department) {
// I do not need the department name here. What I need is the country.
}
}
Проблема заключается в том, что каждый распознаватель может зависеть от различных параметров, чтобы разрешить ответственный служащий. Для меня это звучит как проблема дизайна в моем коде. Я также попытался иметь класс в качестве параметра, чтобы сохранить все значения, которые могут быть необходимы по стратегии, такие как:
class StrategyParameter {
private String department;
private String country;
public String getDepartment() ...
}
interface ClerkResolver {
String resolveClerk(StrategyParameter strategyParameter);
}
Но если честно, я не удовлетворен этим решением, потому что я должен изменить параметр класс каждый раз, когда стратегия нуждается в новом/другом аргументе. А во-вторых, вызывающая сторона стратегии должна установить все параметры, потому что он не знает, какая стратегия решит клерка, поэтому он должен предоставить все параметры (но это не так уж плохо).
Опять же, для меня это звучит как проблема дизайна в моем коде, но я не могу найти лучшего решения.
--- РЕДАКТИРОВАТЬ
Основная проблема с этим решением является при создании задачи. Служба задачи выглядит следующим образом:
class TaskService {
private List<ClerkResolver> clerkResolvers;
Task createTask(StrategyParamter ...) {
// some stuff
for(ClerkResolver clerkResolver : clerkResolvers) {
String clerk = clerkResolver.resolveClerk(StrategyParameter...)
...
}
// some other stuff
}
}
Как вы можете видеть, когда TaskService используются, вызывающие должны предоставить необходимую информацию для решения клерка, то есть название отдела и/или в стране, потому что сам TaskService не имеет такой информации.
Когда задача должна быть создана, вызывающий должен предоставить StrategyParameter, потому что они необходимы для решения клерка. Опять же, проблема в том, что у вызывающего нет всей информации, то есть он не знает о стране. Он может устанавливать только название отдела. Вот почему я добавил второй метод интерфейса, чтобы гарантировать, что стратегия может справиться с разрешения клерка:
interface ClerkResolver {
String resolveClerk(StrategyParameter strategyParameter);
boolean canHandle(StrategyParameter strategyParameter);
}
На риск повторения меня, это решение не кажется мне правильным.
Итак, если у кого-то есть лучшее решение этой проблемы, я был бы признателен за это.
Спасибо за ваши комментарии!
Как вы сказали, вызывающий не может знать, какая стратегия разрешит клерка, поэтому он должен всегда предоставлять все данные. Итак, почему у вас нет метода стратегии для всех возможных параметров? –
Потому что я не хочу менять evertime подписи типа метода, добавляется новая стратегия, для которой нужен новый параметр. Я хочу сохранить его. Вот почему я создал второе решение с классом параметров. – Phillip
Почему бы не использовать шаблон Builder для класса StrategyParameter? – Mikhail