Pull to refresh

Comments 5

Джошуа Блох советует в данном случае со switch использовать внутренний класс-стратегию внутри вашего enum, чтобы избавиться от switch.
Не спорю, данный вариант тоже подходит, но суть архитектуры в том, что она завязана на дженериках и трансферах, а в случае, который советует Блох получается сильная привязка к enum — у, чего мне совсем не хотелось, т к данное поле изначально не являлось обязательным для бизнес логики.

Проблема также решается без Spring с помощью Java Service Providers.
https://docs.oracle.com/javase/tutorial/ext/basics/spi.html
Можно динамически подгружать реализации некоторого интерфейса и его билдера и выбирать их по какой-нибудь метаинформации без switch (итерируя доступные в рантайме и выбирая нужную).

Посмею сделать небольшое замечание, по поводу автовайринга ApplicationContext-а в фабрику. Это, как заверяют евангелисты, признак плохого тона. Не должен отдельный компонент знать про весь контекст. Думаю фабрику можно переписать иначе:

    @SuppressWarnings("unchecked")
    @Component
    public class RequestBuildersFactoryImpl implements RequestBuildersFactory {
    
        @Setter(onMethod = @__(@Autowired))
        private List<RequestBuilder> builders;
    
        public <T extends Transfer> BaseRequest<T> transferToRequest(T transfer) {
    
            ResolvableType type = ResolvableType.forClassWithGenerics(RequestBuilder.class, transfer.getClass());

            RequestBuilder<T> builder = builders.stream().filter(b -> type::isInstance).findFirst().get();
    
            return builder.createRequest(transfer, stage);
        }    
    }


В части получения билдера из списка могут быть варианты, но основной посыл надеюсь понятен.
Спасибо за комментарий, давно увидел его, никак руки не доходили исправить)
Sign up to leave a comment.

Articles

Change theme settings