需要关于如何设计的建议.组合或继承

本文关键字:组合 继承 于如何 | 更新日期: 2023-09-27 18:09:27

我正在尝试设计一个客户端/服务器解决方案。目前包含三个项目。客户端、服务器和各自使用的库(因为它们都需要很多相同的东西)。

例如,客户机和服务器(在本例中)都以完全相同的方式读取传入数据。因此,客户机和服务器都有自己的MessageReader对象。MessageReader将首先读取传入流数据的前4个字节,以确定数据的长度,然后读取其余部分。这些都是异步执行的。当读取所有数据时,类引发自己的MessageRead事件,或者如果读取时存在IOException,则引发自己的ConnectionLost事件。

这一切都很好。有什么问题吗?客户机和服务器有点不同。例如,虽然它们可以以相同的方式读取数据,但它们不会以相同的方式写入数据。服务器有一个Dictionary的客户端,并有一个Broadcast的方法来写入所有的客户端。客户端只有一个TcpClient,并且只能向服务器发送Write。目前所有这些行为都在各自的WinForm,我想把它移动到ClientServer类,但我有一些问题。

例如,还记得之前我谈到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必须捕获它并基本上重新引发自己的版本(重复代码),因为客户端表单不应该有权访问消息阅读器。

不是解决它的好方法。我想ClientServer都可以从抽象的DataReader派生,但我不认为客户端数据阅读器,服务器也不是。我觉得组合更有逻辑意义,但我想不出一种方法来做到这一点,没有大量的代码重复和混乱的事件处理程序。

哎呀,这个问题有点长了…我希望我的长度不会把任何人吓跑。这可能是一个简单的问题,但我真的不知道该怎么做。

需要关于如何设计的建议.组合或继承

作曲

我甚至没有读你的代码或文本。我发现一般的开发人员(几乎)从不需要继承,但是他们喜欢使用它。

继承是脆弱的。继承很难得到正确的处理。在SOLID中很难控制它。

组合易于理解,易于更改,易于DI、Mock和测试。

固体

尽管关系并不强,但我最终还是使用了继承。它消除的代码重复是值得的。可以将两个类共享的所有事件放置到基类中