Как я могу избежать нарушения Open Closed с параметрами метода?

1

В приведенном ниже коде класс MessageProcessor нарушает принцип Open Closed - для каждой новой реализации IMessage требуется изменение этого класса. Есть ли хороший чистый шаблон для такого сценария, который не нарушает O/C?

public interface IMessage
{
}

public class BlahMessage : IMessage
{
}

public class MoohMessage : IMessage
{
}

public class MessageStream
{
    public void Dispatch(IMessage message)
    {
        var messageProcessor = new MessageProcessor();
        messageProcessor.Handle(message);
    }
}

public class MessageProcessor
{
    public void Handle(IMessage message)
    {
        if (message is MoohMessage)
            Handle((MoohMessage)message);

        if (message is BlahMessage)
            Handle((BlahMessage)message);
    }

    private void Handle(MoohMessage moo)
    {
    }

    private void Handle(BlahMessage blah)
    {
    }
}
Теги:
design-patterns
open-closed-principle
language-agnostic

2 ответа

2

Проблема заключается в том, что класс MessageProcessor пытается реализовать поведение разных классов сообщений.

Вместо этого вы можете добавить метод Process() в IMessage и реализовать его в каждом классе сообщений.

Таким образом, интерфейс выглядит,

public interface IMessage
{
   Process();
}

и метод отправки может вызвать этот метод напрямую

public void Dispatch(IMessage message)
{
  message.Process();
}
  • 0
    Но это нарушает SRP, что, возможно, еще хуже. Сообщения - это просто сообщения. Они не содержат логики, необходимой для обработки самих себя, что даже не имеет смысла.
  • 0
    Я не осознавал, что объекты Message были обычными DTO. В этом случае другой вариант - создать IMessageProcessor и реализовать IBlahMessageProcessor и IMoohMessageProcessor. Затем вы можете либо внедрить объект IMessageProcessor в метод Dispatch (), либо использовать шаблон Factory для создания объекта Processor (если вы не возражаете против фабричного класса, нарушающего OCP ).
Показать ещё 1 комментарий
0

Разве ваш текущий MessageProcessor нарушает SRP, потому что он обрабатывает несколько видов сообщений?

Здесь есть возможность рассмотреть:

  • Измените MessageStream для отправки сообщений диспетчеру.
  • Создавайте отдельные классы обработки сообщений.
  • Зарегистрируйте каждый процессор сообщений с Диспетчером во время выполнения.
  • Диспетчер отправит сообщения на правильный процессор.

Конечно, этот подход может просто переключить проблему OCP в другое место, где экземпляры MessageProcessor создаются и регистрируются с Диспетчером. Но, по крайней мере, он очистит многие вызовы if (message is XXX).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню