Как отделить сообщение от его информации и реализации? - PullRequest
0 голосов
/ 07 марта 2020

Сценарий, написанный на языке C#, три основных проекта в моем решении: Remote, Event и Model.

Удаленный: управление сокетом из удаленной системы. Remote имеет два обработчика: для уведомления о состоянии соединения отправьте сообщение из удаленной системы.

Событие: publi sh сообщения по всему решению

Модель: businnes logi c.

Я хочу, чтобы Remote был изолирован от остальной системы, я имею в виду создание менеджера в Model, который перехватывает уведомления от Remote и использует Event для распространения сообщения. Я хочу, чтобы все остальные менеджеры в модели знали только Модель, но не Удаленную реализацию сообщения.

Я уже сделал пользовательские сообщения для публикации sh Событием состояния соединения из Удаленного, моя проблема заключается в следующем: Как я могу отправить сообщение без того, чтобы кто-то перехватил сообщение, знает о реализации? Каждое сообщение имеет разные свойства.

Я пытался создать сообщение в модели, которая имеет такой же интерфейс сообщения в удаленном режиме.

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

Сообщение, которое отправляется вокруг модели по событию

MessageEvent: IEvent

public const string Name="MessageEvent"

// The message implemented in Remote
public IRemoteMessage RemoteMessage {get; private set;}

public void MessageEvent(IRemoteMessage rm)
{
    // I want to avoid make a copy of the original message, too much classes to have same information
    RemoteMessage = rm;
}

Обработчики с Remote в CommunicationManager в модели


RemoteService.ReceivedData += OnReceiveData;

OnReceiveData(object sender, DataArgs e)
{
    var remoteMessage = e as IRemoteMessage;
    EventService.Publish(new MessageEvent(remoteMessage))
}

Каждый может зарегистрировать событие (наблюдатель) в модели как:

EventService.Register(OnManageData, MessageEvent.Name)

\\..

private void OnManageData(EvtData arg)
{   
    if (arg is MessageEvent)
    {
        var me = arg as MessageEvent;

        // I have the problem here, I can cast remoteMessage by its impementation in Remote to get the properties but I don't want it!!!
        var remoteMessage = me.RemoteMessage;
    }
}

Все работает в моем реальном сценарии, но Я повторяю себя:

  1. Remote не должен ссылаться на модель или событие
  2. Модель должна передавать CommunicationManager сообщение от Remote всем остальным менеджерам в модели
  3. Никто не должен знать о реализации удаленного сообщения

Все предложения будут оценены

1 Ответ

1 голос
/ 02 апреля 2020

Я рекомендую использовать «Шаблон проектирования моста». Мост является структурным шаблоном проектирования, который делит бизнес-логики c или огромный класс на отдельные иерархии классов, которые могут разрабатываться независимо.

- пример отправки нескольких типов сообщений с несколькими входными параметрами:

/// <summary>
/// The 'Abstraction' class
/// </summary>
public abstract class Message
{
 public IMessageSender MessageSender { get; set; }
 public string Subject { get; set; }
 public string Body { get; set; }
 public abstract void Send();
}

/// <summary>
/// The 'RefinedAbstraction' class
/// </summary>
public class SystemMessage : Message
{
 public override void Send()
 {
 MessageSender.SendMessage(Subject, Body);
 }
}

/// <summary>
/// The 'RefinedAbstraction' class
/// </summary>
public class UserMessage : Message
{
 public string UserComments { get; set; }

 public override void Send()
 {
 string fullBody = string.Format("{0}\nUser Comments: {1}", Body, UserComments);
 MessageSender.SendMessage(Subject, fullBody);
 }
}

/// <summary>
/// The 'Bridge/Implementor' interface
/// </summary>
public interface IMessageSender
{
 void SendMessage(string subject, string body);
}

/// <summary>
/// The 'ConcreteImplementor' class
/// </summary>
public class EmailSender : IMessageSender
{
 public void SendMessage(string subject, string body)
 {
 Console.WriteLine("Email\n{0}\n{1}\n", subject, body);
 }
}

/// <summary>
/// The 'ConcreteImplementor' class
/// </summary>
public class MSMQSender : IMessageSender
{
 public void SendMessage(string subject, string body)
 {
 Console.WriteLine("MSMQ\n{0}\n{1}\n", subject, body);
 }
}

/// <summary>
/// The 'ConcreteImplementor' class
/// </summary>
public class WebServiceSender : IMessageSender
{
 public void SendMessage(string subject, string body)
 {
 Console.WriteLine("Web Service\n{0}\n{1}\n", subject, body);
 }
}

/// <summary>
/// Bridge Design Pattern Demo
/// </summary>
class Program
{
 static void Main(string[] args)
 {
 IMessageSender email = new EmailSender();
 IMessageSender queue = new MSMQSender();
 IMessageSender web = new WebServiceSender();

 Message message = new SystemMessage();
 message.Subject = "Test Message";
 message.Body = "Hi, This is a Test Message";

 message.MessageSender = email;
 message.Send();

 message.MessageSender = queue;
 message.Send();

 message.MessageSender = web;
 message.Send();

 UserMessage usermsg = new UserMessage();
 usermsg.Subject = "Test Message";
 usermsg.Body = "Hi, This is a Test Message";
 usermsg.UserComments = "I hope you are well";

 usermsg.MessageSender = email;
 usermsg.Send();

 Console.ReadKey();
 }
}

Для получения дополнительной информации см. Следующую ссылку:

Шаблон проектирования моста

...