ООД и ответственность

Я хотел бы думать, что я был в этой области в течение довольно долгого времени, но иногда простые вещи заставляют вас задаться вопросом... решить, какую ответственность несет класс, SRP, и тому подобное.

Итак, в контексте системы обмена сообщениями это:

Message m = new Message();
// Some properties set
m.Send();

или же

Message m = new Message();
// Some Message properties set...
MessagingSystem ms = new MessagingSystem();
ms.SendMessage(m);

Используете ли вы тип контроллера / диспетчера? Если нет, как сообщение может знать, как отправить себя?

5 ответов

Решение

Достаточно взглянуть на саму платформу.NET, чтобы увидеть, как это делается. Каждый объект должен иметь только одну ответственность:

        SmtpClient client = new SmtpClient();
        MailAddress from = new MailAddress("jane@contoso.com", "Jane Clayton");
        MailAddress to = new MailAddress("ben@contoso.com");
        MailMessage message = new MailMessage(from, to);
        message.Body = "This is a test e-mail message sent by an application.";
        message.Subject = "Test message";
        client.Send(message);

Мать-природа имеет решение. Если мы посмотрим на реальный мир, сообщение (электронная почта, письмо, смс...) не отправляется само по себе, но для его отправки требуется устройство, контроллер, менеджер или утилита. Поэтому я думаю, что я бы хотел иметь класс контроллера / менеджера / утилиты, который знает, как отправить сообщение.

Я бы сказал, что второй пример лучше. Какое сообщение имеет отношение к отправке? Отправить куда? Как? Это поднимает слишком много вопросов, и это должно быть первым, что настораживает, что это не так, как все должно работать.

С другой стороны, например. MessagingSystem.SendToCustomerInbox(Message message) прекрасно заявляет, что он делает. Отправляет сообщение в почтовый ящик клиента. Все вопросы, которые мы задали бы себе в первом случае, совершенно ясны.

Сообщение само по себе является скорее представлением данных, и это была бы его единственная ответственность. То же самое и с сервисом отправки сообщений - его обязанность - просто отправлять сообщения, ни больше, ни меньше.

Оба дизайна хороши, в зависимости от ваших требований. Это вопрос простоты использования и разделения

Просто взгляните на разницу между шаблонами Active Record и Data Mapper. Это в значительной степени тот же случай, что и ваш пример.

Вероятно, существует не только черно-белое изображение, поэтому любой смешанный подход, который может быть неоптимальным и лучшим для каждого тела, в одних случаях может сработать, а в других - не получится.

Я считаю, что если сообщение содержит только некоторые данные и может быть отправлено разными способами (асинхронно, синхронно...) или по разным каналам (электронная почта, пейджер, wcf, tcp, факс, речь...), то сообщение классовая ответственность состоит только в том, чтобы держать данные, и там будут менеджеры, как MessagingManager или другие классы, которые будут знать, что делать и как обрабатывать сообщение, как его отправить и как его получить.

как я уже сказал, вероятно, нет идеального или лучшего решения для каждого конкретного случая.

Другие вопросы по тегам