需要关于如何设计的建议.组合或继承
本文关键字:组合 继承 于如何 | 更新日期: 2023-09-27 18:09:27
我正在尝试设计一个客户端/服务器解决方案。目前包含三个项目。客户端、服务器和各自使用的库(因为它们都需要很多相同的东西)。
例如,客户机和服务器(在本例中)都以完全相同的方式读取传入数据。因此,客户机和服务器都有自己的MessageReader
对象。MessageReader
将首先读取传入流数据的前4个字节,以确定数据的长度,然后读取其余部分。这些都是异步执行的。当读取所有数据时,类引发自己的MessageRead
事件,或者如果读取时存在IOException
,则引发自己的ConnectionLost
事件。
这一切都很好。有什么问题吗?客户机和服务器有点不同。例如,虽然它们可以以相同的方式读取数据,但它们不会以相同的方式写入数据。服务器有一个Dictionary
的客户端,并有一个Broadcast
的方法来写入所有的客户端。客户端只有一个TcpClient
,并且只能向服务器发送Write
。目前所有这些行为都在各自的WinForm,我想把它移动到Client
和Server
类,但我有一些问题。
例如,还记得之前我谈到MessageReader
以及它如何同时引发MessageRead
事件和ConnectionLost
事件吗?好吧,现在有一点问题,因为在设计Client
类时,我必须捕获这两个事件并重新引发它们,因为客户端表单不应该访问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
引发MessageReceieved
处理程序时,Client
必须捕获它并基本上重新引发自己的版本(重复代码),因为客户端表单不应该有权访问消息阅读器。
不是解决它的好方法。我想Client
和Server
都可以从抽象的DataReader
派生,但我不认为客户端是数据阅读器,服务器也不是。我觉得组合更有逻辑意义,但我想不出一种方法来做到这一点,没有大量的代码重复和混乱的事件处理程序。
哎呀,这个问题有点长了…我希望我的长度不会把任何人吓跑。这可能是一个简单的问题,但我真的不知道该怎么做。
作曲
我甚至没有读你的代码或文本。我发现一般的开发人员(几乎)从不需要继承,但是他们喜欢使用它。
继承是脆弱的。继承很难得到正确的处理。在SOLID中很难控制它。
组合易于理解,易于更改,易于DI、Mock和测试。
固体尽管关系并不强,但我最终还是使用了继承。它消除的代码重复是值得的。可以将两个类共享的所有事件放置到基类中