Интерфейс наследования интерфейса

1

У меня есть иерархия.

public interface IIncomingMessage : IMessage
{
    String Source { get; set; }
    void ProcessMessage();
}


public interface IOutgoingMessages : IMessage
{
    void SendMessage();
}

У меня есть клиент, который использует метод Static CreateMessage для генерации моего сообщения.

IMessage message = MessageFactory.CreateMessage("incomingA");
messageA.ProcessMessage();

Однако единственный способ, которым я могу это сделать, - добавить параметр ProcessMessage() в IMessage. Однако, если я это сделаю, я должен реализовать это в IOutgoingMessage.

Теперь, когда я пишу это, я вижу, что могу просто избавиться от сообщения. Должен ли я? Или есть лучший способ сделать это?

Теги:
inheritance

4 ответа

4
Лучший ответ

Основываясь на том, как вы используете фабрику CreateMessage, вы ожидаете, что ProcessMessage является распространенным методом для всех типов сообщений IMessage. Основываясь на том, как вы ожидаете, что ваш код будет работать, я бы сказал, что IMessage должен иметь интерфейс метода ProcessMessage.

Однако, глядя на небольшой фрагмент кода, мне кажется, что ваше намерение - не всегда обрабатывать сообщение, а делать это только в IIncomingMessage реализации IIncomingMessage. Поэтому ваш заводский подход не сработает. Т. Кили предлагает иметь два фабричных метода CreateInboundMessage и CreateOutboundMessage могут иметь больший смысл, поскольку у вас разные типы поведения для обоих типов сообщений. Затем эти методы возвращают IIncomingMessage и IOutgoingMessage, а затем вы можете обрабатывать их или обрабатывать их соответствующим образом.

IMessage настоящее время IMessage используется в качестве интерфейса маркера. Если вы видите необходимость в этом - будь то ограничение для дженериков (например, MyCollection<T> where T: IMessage), тогда сохраните его. Но если он действительно не описывает поведение или общий набор свойств/методов или если он не будет использоваться в качестве полезного маркера, то я не уверен, какую пользу он предоставляет.

Опять же, это основано на простом просмотре кода. Я предполагаю, что за сценой появляется больше действий и функциональных возможностей. Удачи!!

1

Я попытаюсь упростить, добавив еще один пример этого сценария:

public class Animal
{
    void Run();
}

public class Giraffe : Animal
{
    void ExtendNeck();
}

public class Monkey : Animal
{
    void EatBanana();
}

Теперь все в порядке, если я теперь добавлю EatBanana() в Animal? Как вы заметили, не все разработчики IMessage ProcessMessage() и в этом примере не все животные EatBanana(). Каков другой способ выполнить то, что вы пытаетесь сделать? Используйте IMessage только в том случае, если у вас есть общие функции для совместного использования между вашими классами. Если у вас их нет, нет необходимости в inteface. Имейте YAGNI в виду. Вы можете добавить его позже, если есть общие функции. Если вы хотите создать IncomingMessage и вызвать специальные методы IncomingMessage, просто создайте строго типизированный IncomingMessage и работайте с ним. Возможно, вам даже не нужен статический заводский метод.

0

(если "MessageFactory.CreateMessage(" incomingA ") возвращает объект типа IIncomingMessage)

либо используйте var

var message = MessageFactory.CreateMessage("incomingA");
message.ProcessMessage();

или отдать результат

IMessage message = MessageFactory.CreateMessage("incomingA");

     if (!(message is IIncommingMessage))
        throw new InvalidOperationException();

     (message as IIncommingMessage).ProcessMessage();
  • 0
    Хотя этот подход будет работать. Я думаю, что это некрасиво. Благодаря лучшему дизайну, OP не нужно ставить эти типы проверок повсеместно.
  • 0
    Я согласен, но я просто пытался ответить на вопрос - не критиковать дизайн.
0

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

Ещё вопросы

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