我正在设计.NET库,我正在寻找关于类组织和命名空间的一些反馈。
假设我有一个抽象的Message
类,它位于根名称空间Foo
中。 Message
针对不同的消息类型有许多具体的实现。鉴于将有许多具体的实现(让我们假设20,甚至更多),是否期望这些具体类型存在于单独的命名空间中,如Foo.Messages
?
我担心使用太多具体Message
类来混淆命名空间,我的库的用户很少需要直接使用这些类。你在使用图书馆时有什么期望?
修改
另外,如果我将具体类分组为Foo.Messages
,那么抽象类是否也应该存在于那里,或者是否应该保留在Foo
中?
答案 0 :(得分:5)
如果您的库的用户不构建您的具体实现类(它们通过工厂模式来获取实例,并且仅通过抽象基类型访问实例),请考虑将您的具体实现类内部化。这将使他们远离用户的代码完成选择。
在Foo.Messages命名空间下对所有具体实现类进行分组听起来不错。你也不想走得那么远 - 为小事创建很多命名空间对用户来说是一个巨大的烦恼。
答案 1 :(得分:0)
如果您正在创建一个库并使用具有许多具体实现的抽象Message类,那么从库的用户隐藏所有具体实现并向Factory类提供一个将返回一个抽象Message的返回类型(返回类型)通常是一个好主意。 ,实际的返回对象当然是具体的),如果对于库的客户端来说是好的,它通常是封装为20个甚至更多的类,并以一种非常方便的方式提供对所需功能的访问。
答案 2 :(得分:0)
一种加载的问题,但是如果问题是有太多的类阻碍了可发现性,那么解决方案的一部分可能会使这些类中的一些internal
而不是public
?如果用户不会直接实例化这些,那么这可能是解决杂乱问题的一部分。
它确实非常依赖于您正在设计的API的性质,并且在某种程度上取决于品味。通常会有一个主要类或一组类,您的用户将在大多数时间直接访问,例如NLog的Logger
,或AutoMapper的Mapper
,或NoRM的Mongo
,或类工厂一般来说。这些应该是前面的和中心的并且是可发现的,并且你可以强有力地证明最好在你的根命名空间中拥有它。
对于其他课程(更多关于实施而不是关于API的课程),显然你想要有条理,但你可以放心地玩,并以一种让你自然的方式组织,只要因为用户需要查找的API部分是最明显的。 Foo.Messages
似乎是一种完全合理的开始方式。另一方面,如果90%的类是Message
子类,但是服务器消息和客户端消息,或者紫色消息和格子消息之间存在重要区别,可能是Foo.Server
或Foo.Plaid
是适合您的命名空间。