c# - 如何将消息与其信息和实现脱钩?
问题描述
C#语言编写的场景,我的解决方案中的三个主要项目:Remote、Event和Model。
远程:管理来自远程系统的套接字。远程有两个处理程序:通知连接状态,从远程系统发送消息。
事件:围绕所有解决方案发布消息
模型:商业逻辑。
我希望 Remote 与系统的其余部分隔离,我的意思是在 Model 中构建一个管理器,它拦截来自 Remote 的通知并使用 Event 来传播消息。我希望模型中的所有其他管理人员只知道模型,而不知道消息的远程实现。
我已经制作了自定义消息以通过 Event 发布来自 Remote 的连接状态,我的问题如下:我如何在没有谁拦截消息知道实现的情况下发送消息?每条消息都有不同的属性。
我试图在模型中制作一个消息,它与远程消息的接口相同。
但是在这种情况下每个人都可以注册模式来获取消息,但必须知道消息获取属性的实现。
通过事件在模型周围发送的消息
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;
}
模型中 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;
}
}
一切都在我的真实场景中有效,但我重复我自己:
- 远程没有引用模型或事件
- Model 必须通过 CommunicationManager 将消息从 Remote 传播到 Model 中的所有其他管理器
- 没有人知道远程消息的实现
每一个建议将不胜感激
解决方案
我推荐使用“桥梁设计模式”。Bridge 是一种结构设计模式,将业务逻辑或巨大的类划分为可以独立开发的独立类层次结构。
这里是一个使用多个输入参数发送多种类型消息的示例:
/// <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();
}
}
有关更多信息,请参阅以下链接:
推荐阅读
- javascript - 在javascript / jQuery中使用数据库中的下拉值附加/复制表行
- batch-file - 使用批处理文件根据其内容重命名多个 JSON
- javascript - 使用jquery,从更大的兄弟组中提取每组相邻的兄弟,匹配选择器
- git - 如何使用单个脚本更新我所有的本地 git 分支?
- php - mysqli_num_rows() 返回不正确的行数
- python - [nodeJS][python-shell]如何使用python-shell发送图片?(nodejs到python)
- python - 不能在 Pytorch 中与导入一起使用
- python - 多个线程访问 GPU 上的同一模型进行推理
- django - 中间件更新 request.user,但 request.user 在视图中变为 AnonymousUser
- javascript - 从 unsplash API reactjs 中选择一个随机图像