请求有关类设计,继承/聚合的建议

时间:2010-05-02 23:27:54

标签: c# mocking class-design aggregate wrapper

我已经开始在.NET中编写自己的WebDAV服务器类了,我开始使用的第一个类是WebDAVListener类,模仿HttpListener类的工作方式。

由于我不想重新实现核心http协议处理,我将使用HttpListener来获取它的所有价值,因此我有一个问题。

建议的方法是什么:

  • 实现HttpListener中的所有方法和属性,只需更改重要的类类型(即GetContext + EndGetContext方法将返回WebDAV上下文的不同类),并存储和使用HttpListener对象内部
  • 通过传递一个HttpListener类来构造WebDAVListener来使用?
  • 使用接口为HttpListener创建一个包装器,并通过传递一个实现此接口的对象来构造WebDAVListener?

如果将HttpListener(伪装或其他)传递给WebDAVListener的路径,是否会通过属性公开底层侦听器对象,或者您希望使用该类的程序保持对底层{{{ 1}}?

此外,在这种情况下,您是否会通过HttpListener公开HttpListener的一些方法,例如Start和Stop,或者您是否会再次期望使用它的程序保留WebDAVListener 1}}参考所有这些事情?

我最初的反应告诉我,我想要一个组合。首先,我希望我的HttpListener类看起来像一个完整的实现,隐藏在它下面有一个WebDAVListener对象的事实。

另一方面,我想构建单元测试而不实际启动网络服务器,所以某种类型的模拟能力也很好,这表明我想要接口包装方式。 / p>

我可以解决这个问题的一种方法是:

HttpListener

然后我会在我自己的类中实现HttpListener的所有方法(至少所有那些有意义的方法),主要是将链接调用到底层的HttpListener对象。

您怎么看?

最后一个问题:如果我采用接口的方式,假设接口将1对1映射到HttpListener类,并且只是为了添加对mocking的支持而编写,那么这样的接口称为包装器还是适配器? / p>

1 个答案:

答案 0 :(得分:1)

我将首先回答你的上一个问题:如果一个类使用匹配一些ISource的包含对象实现一些ITarget接口,那么它就是一个适配器 - 一个从ISource到ITarget的适配器。在这种情况下,没有源接口,你试图添加一个,所以我称之为包装器。

我倾向于

  • 创建一个WebDavListener类,它具有自己的行为所需的所有方法,在内部使用HttpListener,并且不公开有关该HttpListener的任何内容。

  • 如果您需要它,请按照您的建议制作IHttpListenerWrapper和HttpListenerWrapper,并更改WebDavListener以在其构造函数中使用IHttpListenerWrapper。假设所有方法都相同,这应该是一个简单的搜索和替换。您甚至可以将原始构造函数保留在那里并让它构造一个包装器并调用新的构造函数。

  • 如果您需要它,请为它实现一个IWebDavListener,如果您认为您可能需要一个虚拟WebDAV监听器来进行其他事情的单元测试。

这种设计问题就是为什么我喜欢像ReSharper这样的重构工具:Extract Interface,Create Derived Implementation等。让你更容易做出这些改变,所以你现在或以后都不用担心是否要这样做: - )(假设你以后可以随意自由更改来源,当然,这取决于你如何交付东西。)