Нотификации - в реальном мире это очень сложная тема, с большим количеством подводных граблей и регулярно меняющимися требованиями. Давайте посмотрим какие сущности у нас тут есть с точки зрения принципа единственной ответственности (SRP):
1. Канал уведомления (NotificationChannel). Вот это то самое: Email, SMS, Telegram, Slack, VK и т.д. Его ответственностью является отсылка сообщения определенным способом (определенный текст в определенный адрес). Я бы написал его интерфейс так:
interface NotificationChannel {
void send(String to, String text);
}
2. Уведомлятель (Notifier). Его ответственностью является формирование уведомления. И тут тоже возможны варианты, поскольку разных пользователей нужно уведомлять о разных событиях и разным образом. Его ответственостью является сформировать текст сообщения и отправить через определенный канал. Интерфейс выглядит примерно так:
interface Notifier {
void notify(User user, Event event);
}
3. Дальше возможны варианты. В частности формирование текста сообщения можно выделить в отдельную ответственность, создав класс (или интерфейс) NotificationFormatter. Если предусматривается настройка каналов уведомления для каждого пользователя, то может потребоваться какой-нибудь NotificationChannelManager и т.д. Погружаться в эту кроличью нору можно очень глубоко. Все зависит от того насколько детально вы хотите разложить подсистему на объекты.
Лично я бы начал как минимум с интерфейса Notifier, который позволяет "закрыть" подробности реализации подсистемы уведомлений от вызывающего кода. Эта граница, на мой взгляд, лишней не будет. А затем уже, по желанию или при необходимости, раскладывал его реализацию на отдельные, несвязанные классы.