Код, который я пишу (MyService
), включает возможность для каждого клиента подключать свой собственный калькулятор в определенный момент обработки. Это позволяет настраивать бизнес-правила. В момент расчета мы знаем множество вещей, некоторые из которых могут иметь отношение к расчету. MyService
будет создано для определенного набора входных параметров и будет запущено один раз.
Мой план состоит в том, чтобы использовать внедрение зависимостей, чтобы дать MyService
a calculator
в конструкторе. Это позволяет различным пользователям подключать свои собственные calculator
. calculator
вернет сумму, представляющую надбавку, подлежащую уплате за этот конкретный прогон MyService
. Другие будут внедрять различные калькуляторы, и мне нужно будет обновить мой код, не нарушая их. то есть. сохранить обратную совместимость.
Проблема, с которой я столкнулся, заключается в том, что для различных реализаций калькулятора требуются разные параметры. Эти параметры не могут быть введены конструктором в калькулятор во время создания MyService
, поскольку они не известны, происходит некоторая обработка в MyService
.
Калькулятор будет вызываться только один раз в конкретном экземпляре MyService
. Поэтому в одном крайнем случае все параметры могут быть переданы в конструктор, и есть метод без параметров, который возвращает ответ. С другой стороны, все параметры передаются в вызове метода.
AlwaysZeroCalculator
может просто return 0
, поэтому параметры не требуются. PercentageCalculator
необходимо amount
, чтобы применить процент. Еще более сложный нужен amount
и customerNumber
. Мы можем предположить, что все, что может понадобиться calculator
, известно MyService
во время выполнения (или само может быть внедрено в реализацию calculator
, например, в Hibernate Session).
Как я могу это реализовать?
Вот несколько вариантов и проблем:
- Заставить все калькуляторы реализовать интерфейс, который включает все параметры в качестве аргументов метода. Но если что-то добавить, то все они должны измениться, что неизбежно превратит это во второй вариант.
- Создание различных интерфейсов (
ICalculator
, ICalculatorWithAmount
, ICalculatorWithAmountAndCustomerNumber
и т. Д.). MyService
нужно будет увидеть, какой интерфейс реализует calculator
, который он реализует, привести его к этому интерфейсу, а затем вызвать соответствующий метод calculate(..)
.
- Введите объект параметра, который включает в себя все, что волнует любого из них. Это означает, что даже самый простой
calculator
зависит от всего.
- Создайте разные интерфейсы и разные версии
MyService
, которые ожидают один из этих интерфейсов.
- Введите
calculatorFactory
вместо calculator
. Фабрика примет все возможные параметры и создаст калькулятор только с правильными. Это, кажется, просто перемещает проблему куда-то еще, не решая ее.
- Передайте какой-нибудь ужасный хэш-карту калькулятору и введите безопасность, будьте прокляты декларации зависимостей
Есть ли лучший способ?