什么时候应该将类或模块放在单独的Assembly / DLL中?


22

是否有任何准则来决定何时将一个类放在其自己的程序集中/ DLL中?我经常看到两种思想流派:

1)每个类的“分组”都属于其自己的DLL,例如存储库,服务,DTO,基础结构等。

2)一切都应在单个DLL中,但应通过名称空间/文件夹分开,例如,具有“ Core” DLL以及其他名称空间,例如Core.Repositories,Core.Services,Core.DTO等。

在工作中,我们将所有组件都集中在一个称为“业务”的程序集中。有一些文件夹,但没有真正的分离-业务对象(带有逻辑,其中一些甚至不应该是类)被放在“ BusinessObjects”文件夹中而不用管。多个类中使用的内容位于“ Core”文件夹中。实用程序位于“实用程序”文件夹中,数据访问基础结构位于“数据”文件夹中-您就明白了。

对于我正在使用的新模块,我希望/需要一个单独的数据访问层(认为是基本的存储库实现),但我不想将其与其他160个一起放到“ BusinessObjects”文件夹下!在那里上课。同时,我担心创建一个新的类库,因为每个人都习惯于将一个类填充到单个库中。文件夹/命名空间可以工作。

Answers:


12

我发现在每个项目中拥有更多按类别划分类别的项目(即程序集)比在所有名称空间中包含所有这些类的项目更好。您应该使您的项目具有可重用性,并代表应用程序中的不同层。然后,您可以在将来的应用程序中重用这些项目,而不必包括一大堆不必要的类。

例如,根据您提到的内容,我肯定会拥有以下项目:

  • 核心
  • 数据
  • 域(或BusinessObjects)
  • 服务
  • 实用程序(或助手)

2
遗憾的是我不能否决答案。这正是我们公司所建议的。结果有6个左右的项目(例如,对于中型网站),您无法维护基于功能的目录层次结构等。结果,您最终得到了6个项目,每个项目都很难浏览一大堆文件。通常,建议这样做的人从来没有尝试过在相对较大的项目中使用基于功能的项目结构(很抱歉直接判断,但是处理这种过度转换的结果确实很痛苦)。果酱的答案建议正确的方法。
alehro

按类别划分类是导致大型项目混乱的原因。按功能/方面划分它们。然后,命名空间将仅反映此划分。并且整个结构将从规格上反映词典。按类别划分类就像在变量名称中添加类型缩写-通常是难闻的气味。
alehro

容易滥用两个提议的解决方案(即太多项目或太少)。在牢记可重用性和低耦合的情况下找到一个良好的平衡,应该会导致可测试性和可维护性更高。
伯纳德

16

SOLID Principles清洁代码的“鲍勃叔叔”马丁在这里概述了三个原则

  • 释放重用等效原理:重用粒度是释放粒度。
  • 通用闭包原则:一起更改的类打包在一起。
  • 通用重用原则:一起使用的类打包在一起。

一般的经验法则是,应使解决方案中的项目数尽可能少。仅在需要时才拆分它们,以实现一个或多个特定的用户故事,或者只有一个程序集会导致可衡量的性能问题(通常是在它们达到几兆字节的大小时)。


2
这些原则+1是很好的准则。将类分为不同的程序集会引入其他设计注意事项(例如,允许每个程序集的哪个版本一起工作),从而增加了总体代码库,从而增加了维护成本。
2014年

1
但是,除了这些原则之外,我还要补充说,打包可能在单独的程序集中被替换或交换的代码通常是一个好主意。该代码将受益于耦合单独的程序集所需的其他注意事项,并将其分开将使测试和比较不同版本变得更加容易。
2014年

4
是的,但是请确保有真正的替换或交换要求。例如,框架和第三方库(NuGet包等)通常需要支持多个IOC容器和多个日志记录框架。另一方面,对于用户区代码,此类抽象通常纯粹是推测性的,不必要的且具有阻碍性的,并且在真正需要它们的极少数情况下最终都不会奏效。
jammycakes 2014年

“只有在为了实现一个或多个特定用户案例而需要这样做时,或者如果使用单个程序集会导致可衡量的性能问题(通常在它们达到几兆字节的大小时),才将它们分开。” -完全随机且不以现实建议为基础
hyankov '17

1
很抱歉,关于它“完全是随机的而不是基于现实的”到底是什么?在多年致力于解决方案的工作之后,我发布了这个答案,该解决方案无缘无故地被分解成比所需更多的项目,而这正是您应该做的事情。结果?冰川编译时间和一团糟的依赖地狱(特别是在NuGet之前的日子)。将它们拆分成单独的程序集会产生成本,如果没有任何好处可以抵消该成本,那么这只是从业务中窃取的一种情况。
jammycakes

4

我使用的其他一些指导原则:

  • 您是否认为您将在其他projectS中重用此代码?对于一组相关的Web应用程序,我们有一个与用户帐户相关的模块,所有应用程序都使用该模块,因为它们都对用户帐户和登录使用相同的模型。我已经通过几何和数学库完成了类似的工作,并通过包含DLL在多个应用程序中重用了它们。

  • 您是否希望能够修改/部署此代码而无需重新部署/重新编译整个项目?有时仅重建模块,部署并重新启动Web应用程序很有用。

听起来在您的情况下,基本的通用存储库将来可能再次有用,如果可以的话,将其分离到新的DLL中可能是值得的。


我认为您的第二点确实是合理的。划分模块应该有助于开发/测试和编译时间。
WM
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.