public interface ResultProvider {
public Type getType(Type type);
public List<DTO> search(SearchOption searchOption);
}
@Component
public class Test1ResultProvider {
public Type getType() {
return Enum.type;
}
public List<DTO> search(SearchOption searchOption) {
repository.find(searchOption);
}
}
@Component
public class Test2ResultProvider {
public Type getType() {
return Enum.type2;
}
public List<DTO> search(SearchOption searchOption) {
repository.find(searchOption);
}
}
@Service
public class ResultService {
private final List<ResultProvider> resultProviders;
public List<DTO> find(SearchOption searchOption) {
return resultProviders.stream()
.filter(provider -> provider.getType() == searchOption.getType())
.findFirst()
.map(provider -> provider.search(searchOption.getType()))
.orElseThrow(() -> new IllegalArgumentException());
}
}
Следует ли рассматривать это как стратегическую модель, поскольку поведение объекта меняется в зависимости от условий? Или мне следует рассматривать это как фабричный шаблон, потому что я возвращаю разные объекты в зависимости от условий? Или, может быть, оба? Если вы знаете этот ответ, пожалуйста, ответьте.
Я думаю, что это стратегическая модель, но мне было интересно, стратегическая ли это модель.
Это наводящий вопрос. Он предполагает, что в каком-то коде существует шаблон проектирования, и требует согласия с этим предположением. Как и в случае с большинством наводящих вопросов о шаблонах проектирования, ответ здесь — ничего из вышеперечисленного. Большая часть кода не является шаблоном (и не должна им быть). Это просто код.
Вы не ошибаетесь, это паттерн Стратегии.
Стратегия: интерфейс ResultProvider
Конкретная стратегия: Test1ResultProvider и Test2ResultProvider
Контекст: ResultService
Клиент: код, который взаимодействует с ResultService.
Вот версия шаблона «Абстрактная фабрика» (не фабричный метод, поскольку нам нужно создать семейство объектов).
public interface ResultProvider {
Type getType();
List<DTO> search(SearchOption searchOption);
}
public class Test1ResultProvider implements ResultProvider {
@Override
public Type getType() {
return Enum.type;
}
@Override
public List<DTO> search(SearchOption searchOption) {
// Implementation
}
}
public class Test2ResultProvider implements ResultProvider {
@Override
public Type getType() {
return Enum.type2;
}
@Override
public List<DTO> search(SearchOption searchOption) {
// Implementation
}
}
public interface ResultProviderFactory {
ResultProvider create();
}
@Component("type")
public class Test1ResultProviderFactory implements ResultProviderFactory {
@Override
public ResultProvider create() {
return new Test1ResultProvider();
}
}
@Component("type2")
public class Test2ResultProviderFactory implements ResultProviderFactory {
@Override
public ResultProvider create() {
return new Test2ResultProvider();
}
}
@Service
public class ResultService {
private final Map<String, ResultProviderFactory> factoryMap;
public ResultService(Map<String, ResultProviderFactory> factories) {
factoryMap = factories;
}
public List<DTO> find(SearchOption searchOption) {
ResultProviderFactory factory = factoryMap.get(searchOption.getType().name());
if (factory != null) {
ResultProvider provider = factory.create();
return provider.search(searchOption);
} else {
throw new IllegalArgumentException("Unsupported type: " + searchOption.getType());
}
}
}
ты забыл
implements ResultProvider
в объявлениях классов?