Видишь ли, каждый лишний класс аукается при инстанцировании. Тут уже затрагивали вопрос IoC, DI и прочее - это как раз оно самое. Для меня инстанцирование по месту вещь неприемлимая в принципе - она просто не дает тестировать.
У вас просто неправильный мед™.
Как подсказывает ВикиПедия — «[In unit testing,] a unit is the smallest testable part of an application.»
Понимаешь, одинокий класс/объект не можно и не нужно тестировать — как ты будешь тестировать тот же почтовый транспорт, который бессмыслен в отрыве от отправщика почты, который использует этот транспорт?
Что касается примера, то зависит опять же от того, где этот код. Если это в сервисном слое выполняется, то в принципе нормальный вариант. ... Но если это в контроллере такое, то сразу возникает масса вопросов, которые я частично выше описывал.
Это зависит от того лишь, на какой слой приходится бизнес-логика принятия решений, и от уровня влияния этих решений, отправка почты может быть с таким же успехом и в модели, (если результат этого действия важен только для модели, например, поставить отметку об отправке письма), но если ты на основании этого действия собираешься изменить текущий контроллер, например, сделав перенаправление на другую страницу — это нормально ловить это исключение в контроллере.
Для меня Tell, Don't ask заключается в простом принципе — никакой объект для выполнения действия не должен запрашивать никакие данные извне, а пользоваться только теми данными, которые ему передал объект стоящий выше него в иерархии приложения. Соответственно, обязанность «старшего» объекта — передать ему нужные данные.
И — да, я не знаю, что такое «легаси». Если не сложно, употребляй русскую терминологию, или полноценную английскую, что бы я мог погуглить, что ты имеешь ввиду, спасибо.