Внедрение зависимостей на основе условий - PullRequest
1 голос
/ 19 февраля 2020

Я использую шаблон разработки стратегии и хочу внедрить различные зависимости, основанные на некоторых условиях.

public interface strategy {
    public void task();
}

public class concreteStrategyOne implements strategy {
    public void task() {
        //task strategy one
    }
}

public class concreteStrategyTwo implements strategy {
    public void task() {
        //task strategy two
    }
}

public class taskInHand {

    private Strategy strategyImpl;

    @Inject
    public taskInHand(Strategy strategyImpl){
        this.strategy = strategyImpl;
    }

    public void use(Object obj) {

      if(obj.get("something") == 1){
            strategyImpl.task();
            // I want to call task() implemented in concreteStrategyOne 
      }
      else if(obj.get("something") == 2){
            strategtImpl.task()
            // I want to call task() implemented in concreteStrategyTwo
      }
}

}

Я знаю, что могу использовать аннотацию @Named в конструкторе для привязки определенных классов c при внедрении но я хочу внедрить различные зависимости в соответствии с условиями, упомянутыми выше.

Итак, чтобы уточнить .. if(object.get("something")) returns 1, я бы хотел запустить task(), реализованный в concreteStrategyOne.

Как это можно сделать?

Ответы [ 2 ]

3 голосов
/ 19 февраля 2020

Вы можете создать StrategyFactory

public Class StrategyFactory {
    @Inject
    // Strategy one impl here
    private Strategy strategyOne;

    @Inject
    // Strategy two impl here
    private Strategy strategyTwo;

    public Strategy getStrategy(String something) {
        if (something.equals("some condition")) {
            return strategyOne;
        } else {
            return strategytwo;
        }
    }
}

Inject StrategyFactory в вашем taskInHand и передать атрибут, который решает, что реализация будет использоваться getStrategy()

public void use(Object obj) {
    strategyFactory.getStrategy(obj.get("something")).task();
}
1 голос
/ 19 февраля 2020

Вы можете использовать провайдера (я думаю, именно так его называет Guice), который выбирает нужную реализацию и внедряет нужную. Но вам нужно предоставить поставщику всю информацию, необходимую для принятия решения. Это может нарушить инкапсуляцию и пару других SOLID идей.

Другой вариант - внедрить коллекцию всех реализаций, выполнить итерацию по коллекции и получить реализации "volounteer", если они обнаружат, что они " Ответственный или подходящий для указанного c варианта использования.

Более подробную информацию о провайдерах можно найти в guice wiki .

...