Допустим, у нас есть команда. У команды есть обработчик и в нем нам нужно отправить письмо (письмо - это прям доменное требование). Подскажите как это делать, чтобы еще и было тестируемо юнит тестами? Просто принимать какой-нибудь swiftmailer, забить на принцип инверсии зависимостей, stub'нуть swiftmailer и пусть так и живет?
Если будете напрямую подключать swiftmailer будете зависеть от него. Сделайте свой Sender, можно в виде интерфейса. Через DI будете подключать нужную реализацию. Вызывайте в команде. Тестируете сам сервис отправки, а не всю команду целиком.
А можно посмотреть реализацию сендера? Тут тогда получается такая ситуация, что если у нас несколько таких команд, то для каждой такой команды нужна реализация интерфейса сендера. А содержание для каждой команды может быть свое, адресаты, копии и тд. для каждый команды может быть свое, то у нас получится куча классов - реализаций интерфейса сендера. Это норм Вы считаете?
superkolya, это норм, если это требуется. Если они разные, то можно делать разные. Если одинаковые, то на все SenderInterface можно повесить один обработчик. Все зависит от конкретных задач. Копипаст не всегда плохо. Иногда оправданно. Но интерфейсы точно должны быть разные везде.