多个项目和一个解决方案有什么好处?

58
当我在企业工作时,我们在解决方案中使用了多个项目 - 用于UI、业务逻辑、数据访问、数据库和打印的项目。现在我在一个新的企业里工作,经理告诉我不需要创建所有这些项目,而是将它们制作为解决方案中单独的目录文件夹。
我只想知道是否需要说服他使用多个项目!

1
你为什么觉得需要多个项目? - Oded
1
阅读MSDN页面-http://msdn.microsoft.com/en-us/library/bb165951(v=vs.80).aspx和SO线程-https://dev59.com/z3I-5IYBdhLWcg3wwbVL - KV Prajapati
1
@Oded:在我以前的企业中,他们告诉我们必须制作多个项目,没有解释(而且是我的错,没有花时间去搜索为什么我们需要它)。 - Akrem
6个回答

97

我对被接受的答案感到非常惊讶。我在两个环境中都工作过,发现多个项目总体上都有益。具体决定仍由您的团队决定(如果一个单一的项目没有阻止您实现目标,则足够了)。

我倾向于使用 Uncle Bob 的OOD 原则来管理软件包。这些原则并不是很出名(特别是与他的用于类设计的 SOLID 原则相比),但它们很合理。

摘自 Uncle Bob 的 OOD 原则

前三个软件包原则是关于软件包内聚性的,它们告诉我们应该把什么放在软件包里:

  • REP 发布复用等价原则:重用的颗粒就是发布的颗粒。
  • CCP 共同封闭原则:一起变化的类应该封装在一起。
  • CRP 共同复用原则:一起使用的类应该封装在一起。

后三个原则是关于软件包间的耦合度,并讨论了评估系统软件包结构的度量标准。

  • ADP 无环依赖原则:软件包的依赖关系图必须没有循环依赖。
  • SDP 稳定依赖原则:要依赖稳定的方向。
  • SAP 稳定抽象原则:抽象程度随稳定性增加而增加。

这些与我的个人经验相符,我倾向于较少的项目通常会导致问题:

  • 较少的软件包可能会导致依赖管理不佳。单独的项目/程序集可以帮助防止在不应该使用的情况下使用内部/私有类和成员。

  • 通常在许多项目中,您会开发一个非常稳定和经过测试的“核心”库集,这些库很少更改。将这些组件保留在自己的项目(甚至解决方案)中可以帮助它们免受高层次的持续变化的影响。

  • 使用较少(或单个)项目导致的大型项目可能非常混乱。Visual Studio不会将您的项目/解决方案镜像到文件结构上,因此即使是有组织的大型项目也可能存在于驱动器上的混沌状态。

  • Visual Studio足够聪明,可以避免重新编译没有更改的程序集。随着您的“核心”项目稳定下来,它们将看到较少的编译,这可以节省编译时间。

  • 同样适用于上述内容,使用较少的项目会导致总是重新编译代码 - 无论是否存在相关更改。非常大的项目中的一行更改将导致完全重新编译。

  • 当然,多个项目也可能存在问题:

    • 必须注意依赖项,以避免循环引用(.NET处理得相当好,但Visual Studio会防止)

    • 您的解决方案可能变得足够大,以需要子解决方案,这可能很棘手

    • 解决方案的初始编译时间可能较慢

    最后,.NET中很少使用的一个功能是单个.DLL可以包含多个模块(实际上是几个程序集共享一个元数据集)。我不建议使用这个功能,但知道它是如何工作的很有趣:http://www.codeproject.com/Articles/9364/Merging-NET-assemblies-using-ILMerge


4
你的回答核心只是对同样被接受的观点的正交视角。他说“何时正确分离”,而你则认为“为什么正确分离是好的”。 - SerG

71

我认同你的经理的观点。

多个项目意味着多个程序集,需要频繁地复制程序集,编译时间会更慢。

如果你只是为了更好地组织代码而使用多个项目,那么你做错了。使用文件夹也可以达到同样的效果。

一些使用多个程序集的合法理由包括:

  • 你正在开发一个插件架构
  • 你需要分别部署不同的程序集
  • 你需要同时使用多种语言
  • 你在创建用于不同位置的库

5
这些不仅是有"有效"理由拥有不同项目/程序集的原因,而且这些理由使得这样做必要。但撇开语义上的小问题不谈,我赞同这个观点。将一个项目映射到一个程序集意味着仅出于组织目的而拆分项目通常不是一个好主意。 - Cody Gray
你能详细说明插件架构中多个程序集的作用吗? - Minh Tran
1
@MinhTran:在插件架构中,您需要(1)一个项目,其中包含定义插件必须实现以及如何与主机应用程序交互的合同(接口),(2)一个引用合同的可执行文件,希望加载插件,以及(3)至少一个作为类库(即DLL)的插件。思路是可执行文件动态加载插件DLL。 - Olivier Jacot-Descombes
多个项目如何消除循环依赖并提高代码组织。项目是您应用程序树的根,以防止其倒塌。 - jwize

9
我发现了一篇有趣的文章,讲述了应用程序中结构(项目或文件夹)的重要性。我认为当你打开一个解决方案并看到项目列表时,它们的名称会给我一个关于应用程序如何构建的提示。 MVP设计模式是其中的一个例子,包括 BLL(业务逻辑层)、DAL(持久化层(映射、约定等))、Web、PL(表示层)和Test(测试肯定需要放在单独的项目中)。
目录结构对你的代码至关重要
“正如任何设计师所说,设计过程中的第一步最为关键。前几笔勾勒出的形式,决定了之后的命运。”- 克里斯托弗·亚历山大
(克里斯托弗·亚历山大是一位建筑师。虽然没有从事过编程工作,但他影响了许多思考编程的人。他早期的著作《模式语言》是设计模式运动的原始启示。他长期思考如何构建美丽的事物,这些思考似乎也很大程度上适用于软件构建。)
在一次 CBC 电台采访中,亚历山大讲述了以下故事(此处略加改编):“我和我的一个学生一起工作。他在构建某个东西时遇到了很大的困难。他完全不知道该怎么做。所以我和他坐在一起,我说:听着,首先要弄清楚最重要的事情是什么。把它搞清楚。耐心点。别太匆忙。想一会儿。当你感觉到已经找到了最重要的事情,并且毫无疑问地确定它确实是最重要的事情时,那就开始做这个最重要的事情。当你完成了这个最重要的事情后,问问自己是否可以让它更美丽。别废话,直接在脑海中搞清楚,能否让它更好。当这一切都完成之后,你感觉再也不能让它更好了,那么就找到下一个最重要的事情。”
应用程序中创建整体形式的第一笔勾勒是什么?就是目录结构。当浏览源代码时,目录结构是程序员遇到的第一件事。一切都从它开始。一切都取决于它。它显然是您源代码中最重要的方面之一。
考虑程序员在遇到不同目录结构时的不同反应。对于按功能分组的风格,应用程序员的想法可能是这样的:
“我明白了。这里列出了应用程序的所有顶级功能。很好。” “看看。我想知道这个项目在哪里....哦,在这里找到了。我需要的其他所有东西也在这里,都在同一个地方。太棒了。” 然而,对于按层次分组的风格,应用程序员的想法可能更像这样:
“这些目录告诉我什么都没有。这个应用程序有多少个功能?我不知道。它看起来和其他所有应用程序完全一样。根本没有区别。太好了。又要开始了......” “嗯,我想知道这个项目在哪里....我猜它的部分遍布整个应用程序,分散在所有这些目录中。我真的拥有我需要的所有东西吗?我想我们以后会发现的。” “我想知道是否仍然遵循那个命名约定。如果不是,我将不得不在另一个目录中查找。” “哇,你看看这个单个目录的大小......天哪。”
在其他领域中按层次分组是无效的。

Source


1
那篇文章来自哪里?而且,那是一个相当大的引用。 - Andrew Barber
1
哈哈,这很好,猜测这是软件开发的哲学分支。这是链接:http://www.javapractices.com/topic/TopicAction.do?Id=205 - Jonathan

6
如果你只有一个应用程序,那么一个项目就足够了。但我认为这是非常罕见的情况。大多数时候,你会有多个应用程序,因此通过拥有多个项目,你可以在这些应用程序之间重复使用组件,而不必像共享源文件一样进行笨拙的操作。

1
此外,如果你拥有分布式的设计,你就不会将应用程序限制为Web应用程序或Windows应用程序。 - mehul9595

5

由于关注点分离,这将极大地帮助类/对象之间的意外引用。

对于WPF/Silverlight程序员,考虑MVVM设计模式:将ViewModels和Views分开成两个不同的项目将确保没有View对象被引用到ViewModel中。

另一个要点是构建时间可能会更短,因为整个解决方案不会每次重新编译。这可能是您向经理提出的一个好论据(但这个假设可能取决于您的解决方案的大小)。


3

如果需要,可以使用不同的项目:

  • 为您的解决方案分离二进制文件,这样您就可以灵活地准备和部署补丁/更新

  • 可以管理插件

  • 例如,在您的C#中使用C++代码。

  • 可重用的组件。在程序集中声明的类型可以在公司的不同应用程序中重复使用,以提供统一的API。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接