Аргументировать довольно просто и даже сослаться на конкретные абзацы из книги Implementing domain-driven design, а именно, то что автор пишет про сервисы. Автор книги довольно четко рассказывает почему сервисы не должны обладать состоянием.
У вас классический сервис и у вас проблема, только лишь потому, что вы впринципе неправильно подошли к проектированию вашего сервиса.
В первую очередь вам нужно спроектировать интерфейс CalculatorInterface
interface CalculatorInterface {
public function calculate($products, $city);
}
Далее вам нужно создать две реализации этого интерфейса CdekCalculator и EmsCalculator
class CdekCalculator implements CalculatorInterface {
public function calculate($products, $city) {
// реализация расчета через cdek
}
}
class EmsCalculator implements CalculatorInterface {
public function calculate($products, $city) {
// реализация расчета через ems
}
}
И теперь ваш класс доставки будет выглядеть таким образом
class Delivery {
private $calculator;
public function __construct(CalculatorInterface $calculator) {
$this->calculator = $calculator;
}
public function calculate($products, $city) {
//тут ещё какая-то логика, которая определяет условия доставки, если она вообще возможна
return $this->calculator->calculate($products, $city);
}
}
Предмета спора больше нет. Вы просто передаете в класс Delivery нужную реализацию калькулятора. Код выше это псевдоязык, не php и вообще только базовая идея того, как это должно быть. У вас наверняка тут же возникнет вопрос, как вам тогда выводить все расчеты доставки в ваш UI. Но извините не могу написать за вас всё приложение.
Это базовые вещи в объектно-ориентированном программировании. Называется полиморфизм подтипов. Без этих знаний невозможно писать хороший объектно-ориентированный код. Лучше оба придите к выводу, что вам срочно нужно почитать какие-нибудь книги об объектно-ориентированном программировании и начать с самых основ, что такое полиморфизм и в частности полиморфизм подтипов.
Вообще protected/private методы и ветвления из условных конструкций - это практически всегда показатель спагетти-кода и первый звоночек, что вы пишете процедурный код используя ООП синтаксис. Вы придете к этому выводу если будете разрабатывать через TDD, а затем сможете нагуглить ваши предположения у других программистов.