У меня есть иерархия.
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.
Теперь, когда я пишу это, я вижу, что могу просто избавиться от сообщения. Должен ли я? Или есть лучший способ сделать это?
Основываясь на том, как вы используете фабрику CreateMessage
, вы ожидаете, что ProcessMessage
является распространенным методом для всех типов сообщений IMessage
. Основываясь на том, как вы ожидаете, что ваш код будет работать, я бы сказал, что IMessage
должен иметь интерфейс метода ProcessMessage
.
Однако, глядя на небольшой фрагмент кода, мне кажется, что ваше намерение - не всегда обрабатывать сообщение, а делать это только в IIncomingMessage
реализации IIncomingMessage
. Поэтому ваш заводский подход не сработает. Т. Кили предлагает иметь два фабричных метода CreateInboundMessage
и CreateOutboundMessage
могут иметь больший смысл, поскольку у вас разные типы поведения для обоих типов сообщений. Затем эти методы возвращают IIncomingMessage
и IOutgoingMessage, а затем вы можете обрабатывать их или обрабатывать их соответствующим образом.
IMessage
настоящее время IMessage
используется в качестве интерфейса маркера. Если вы видите необходимость в этом - будь то ограничение для дженериков (например, MyCollection<T> where T: IMessage
), тогда сохраните его. Но если он действительно не описывает поведение или общий набор свойств/методов или если он не будет использоваться в качестве полезного маркера, то я не уверен, какую пользу он предоставляет.
Опять же, это основано на простом просмотре кода. Я предполагаю, что за сценой появляется больше действий и функциональных возможностей. Удачи!!
Я попытаюсь упростить, добавив еще один пример этого сценария:
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
и работайте с ним. Возможно, вам даже не нужен статический заводский метод.
(если "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();
Вы можете использовать разные классы, которые не наследуют ничего и полностью отделяют процесс. Если вы это сделаете, вы потеряете несколько преимуществ использования подкласса в этом случае. Между ними могут быть сходные свойства, которые облегчат ссылку друг на друга, если оба они распространяют общий класс. Что касается проблемы вашего метода с этими подклассами, вы можете просто предложить родительскому классу общепринятый метод (позвоните на него ProcessMessage()
) и просто попросите каждый подкласс перезаписать поведение такого метода. Таким образом, вам не нужно иметь разные методы, а просто два разных определения. Простые концепции полиморфизма.