Простейший пример: логгер. Все, что он делает - передает дату и сообщение в N мест: консоль, файл, очередь, udp,...
Его можно реализовать по тупому: написать N похожих логгеров для каждого транспорта. Вам придется вручную следить, что бы интерфейс каждого был идентичным. Для многих языков поменять один логгер на другой будет не просто.
Вариант Б: абстрактный логгер и кучка отдельных расширений. Имеет право на жизнь, но это тупиковая с точки зрения дальнейшего развития штука. От логгера, помимо отправки данных часто требуется: фильтрация, агрегирование, роутинг, разная реакция на отличные уровни сообщений и т.д.
Вариант В: используем шаблон adapter. Реализация для каждого транспорта с общим для всех интерфейсом. При этом взаимодействовать будете с адаптером, а не реализациями. Роутинг реализуется (в зависимости от сложности) либо в отдельном классе, либо как часть адаптера, фильтрацию - точно так же и т.д. В этом ваша главная плюшка - независимость разных частей системы.