C# 需要关于如何设计这个的建议。组成还是继承?
我正在尝试设计一个客户机/服务器解决方案。目前它包含三个项目。客户端、服务器和各自使用的库(因为它们都需要很多相同的东西) 例如,客户端和服务器(在本例中)都以完全相同的方式读取传入数据。因此,客户端和服务器都有自己的C# 需要关于如何设计这个的建议。组成还是继承?,c#,winforms,events,C#,Winforms,Events,我正在尝试设计一个客户机/服务器解决方案。目前它包含三个项目。客户端、服务器和各自使用的库(因为它们都需要很多相同的东西) 例如,客户端和服务器(在本例中)都以完全相同的方式读取传入数据。因此,客户端和服务器都有自己的MessageReader对象。MessageReader将首先读取传入流数据的前4个字节,以确定数据的长度,然后读取其余字节。这都是异步执行的。读取所有数据时,类会引发自己的MessageRead事件,或者如果读取时出现IOException,则类会引发自己的Connection
MessageReader
对象。MessageReader
将首先读取传入流数据的前4个字节,以确定数据的长度,然后读取其余字节。这都是异步执行的。读取所有数据时,类会引发自己的MessageRead
事件,或者如果读取时出现IOException
,则类会引发自己的ConnectionLost
事件
所以这一切都很好。有什么问题吗?嗯,客户端和服务器有点不同。例如,虽然它们可能以相同的方式读取数据,但它们不以相同的方式写入数据。服务器有一个客户端的字典
,并有一个广播
方法来写入所有客户端。客户端只有一个TcpClient
,并且只能写入服务器。目前,所有这些行为都在各自的WinForm中,我想将其移动到客户端
和服务器
类,但我遇到了一些问题
例如,还记得我前面提到的MessageReader
以及它如何引发MessageRead
事件和ConnectionLost
事件吗?现在有一点问题,因为在设计客户端
类时,我必须捕获这两个事件并重新引发它们,因为客户端表单不应该访问MessageReader
类。有点难看,看起来像这样:
class Client
{
private MessageReader messageReader = new MessageReader();
public delegate void MessageReceivedHandler(string message);
public delegate void ConnectionLostHandler(string message);
public event ConnectionLostHandler ConnectionLost;
public event MessageReceivedHandler MessageReceived;
public Client()
{
messageReader.ConnectionLost += messageReader_ConnectionLost;
messageReader.MessageReceived += messageReader_MessageReceived;
}
private void messageReader_MessageReceived(string message)
{
if (ConnectionLost != null)
{
ConnectionLost(message);
}
}
private void messageReader_ConnectionLost(string message)
{
if (MessageReceived != null)
{
MessageReceived(message);
}
}
}
这段代码很难看,因为它基本上是重复的代码。当MessageReader
引发messagereceived
处理程序时,Client
必须捕获它并基本上重新引发它自己的版本(重复代码),因为客户端表单不应该有权访问MessageReader
这不是一个很好的解决方法。我认为客户端
和服务器
都可以从抽象的数据读取器
派生出来,但我认为客户端不是数据读取器,服务器也不是。我觉得组合更有逻辑意义,但如果没有大量代码重复和混乱的事件处理程序,我想不出一种方法来实现这一点
哎哟,这个问题有点长了。。我希望我的长度不会吓跑任何人。这可能是一个简单的问题,但我真的不知道该怎么办
感谢阅读。作文
我甚至没有读你的代码或文本。我发现一般开发人员(几乎)从不需要继承,但他们非常喜欢使用它
遗产是脆弱的。继承很难得到正确的结果。很难用固体来控制它
组合易于理解、更改,并且易于DI、模拟和测试
尽管这种关系并不牢固,但我最终还是使用了继承。它消除的代码重复是值得的。能够将两个类共享的所有事件都放到基类中。是的,我目前正在使用composition,但从阅读提供的代码示例中可以看出,它给我带来了一些问题。是的,请投我一票。这太冗长和复杂了,读不懂。@Ryan-我没说你读过。客户端类的职责是什么?它的目的是完成什么工作?如果只是传递MessageReceived和ConnectionLost事件,那么最好使用一个接口来实现所需的解耦。否则,回答这个问题可能会帮助我们提出更好的方法。@Nimrand:Client类可以连接到给定主机名和端口的服务器,维护服务器发送消息时的侦听线程,并将消息发送到服务器。它的成员变量是TcpClient
和MessageReader
。您仍然可以将代码分离为对象,并使用聚合(使用DI)来实现相同的效果。