功能相关的库或单个服务层?

时间:2016-10-11 14:19:32

标签: c# .net architecture n-tier-architecture

我和我的团队正在寻找证据来支持类似功能的多库方法,或者在单个服务层内压缩所有这些功能。重要的是要注意,这将是一个Web api的背后,任何一种方法都是有效的,但我们需要决定哪种方式更有利。为了说明我们正在研究的层,我们将拥有以下内容:

Solution
    WebAPI
    Services ---- This is what we're looking at
    DataAccess

请记住,如果我们使用多库方法,我们仍然会有一个服务项目,但它会更薄,并具有更多特定功能。我们不打算独立部署这些库,但是需要在同一个解决方案中引用它们,或者通过web api访问它们。

我们其他人会提出的建议如下:

Solution
    WebAPI
    Services
    Services.Geography        ---
    Services.Membership       --- This is the alternative approach
    Services.ProductDelivery  ---
    etc...

我们在第一个选项中看到的好处是将所有这些代码组织在一个库中,这样可以更容易地提取重复代码,可能进行单元测试,并且可能会对构建过程有所缓解。

选项二的好处是在项目之间明确划分功能,具有可能在需要时可移植的隔离代码,并且通常能够独立地处理和配置应用程序的不同方面。

我们在选项一中看到的缺点是服务层现在负责应用程序的每个方面,这会使该库膨胀并且在我看来有点违反单一责任。我们意识到规则不像图书馆那样适用于方法和类,但似乎通过分离功能似乎还有其他好处。还有可能错误地将代码放在它不属于的地方,或者使用可能不适用的整个项目可用的类。

选项二的缺点是项目构建的开销明显增加,在配置中工作(即使这可能是可取的),并且可能使解决方案混乱,项目多于必要的项目。我认为我们计划将类似功能整合到单个项目中(即,我们可以在该项目中构建多个ProductDelivery实现,以便能够在它们之间切换或出于不同原因使用不同的实现)。

我们意识到我们所有的业务规则都可以通过任何一种方法来完成,我们只是在决定哪种方法更好的做法时陷入僵局。

所以问题是,这两种方法中的哪一种是更好的做法?

2 个答案:

答案 0 :(得分:2)

我有两件事可以让我考虑选择第​​一个选项:

  • 您的服务仅使用一个数据层库。
  • 您的服务非常简短(类似于实施CRUD)

在库中拆分,一个在整个库中计算几行的类,可能很尴尬。除非,你知道它会增长很多(当然是在几个课程中)。

如果没有,我会说选项2更好,因为:

  • 这样更容易替换部分服务。更改您想要的库,并且已完成。
  • 如果你想避免每个库之间的强耦合,它应该更抽象
  • 测试其中的特定部分应该更容易。
  • 它应该更具可配置性,您可以在项目中配置所有这些参考所有这些(即使,如果一个或多个库没有改变很多东西)。
  • 它应该不像神图书馆
  • 根据您的图书馆的专业程度,它可能更适合其他项目。

我不同意这些观点:

  

单个库,可以更轻松地提取重复代码

如果您小心,您的重复代码可以在父库中提取,与所有其他代码共用。因此,所有重复的代码都应该被自动提取(除非,如果缺乏沟通或者人们更喜欢复制/粘贴代码。但是,一个库不会改变它。甚至可能更难找到代码已存在的位置)。

  

潜在的单元测试

为什么有几个库需要更难测试? 如果您有多个库,则必须使它们更抽象,以允许更改。然后,您的测试应该很容易。

  

并且可能对构建过程有所缓解。

为什么?如果你的所有图书馆都有很好的名字,你的问题会在哪里? 部署dll或几个dll,不应该那么难 如果它关于配置,一个库或更多,你仍然可以使用相同的配置,不一定更多(但可能更多)。

我也不同意单一责任不适用于图书馆。它是。 每个图书馆都应该对一个企业负责,而不是全部。如果你完成了一组库,它就可以成为一个框架。甚至,对于一个框架,你将完成一个单一的责任,但更通用,而不是方法,类,库等的责任......

但您可能需要一位比我更高级的架构师/开发人员的意见。

如果有人不同意我的意见,请不要犹豫,评论我的回答。我很乐意从您的知识中学习

答案 1 :(得分:1)

考虑到我的第一个答案的评论。

  

目前的计划是拥有一个数据层。我们的许多潜力   其他图书馆将是第三方api包装,不会   必然需要与数据库进行交互。那些可以   可能有自己的数据层,可能会或可能不会互动   使用相同的数据库或独立的数据库。我想这样做   使它们自成一体,并且能够在没有其余部分的情况下存在   解。仍然不能完全确定这是否是我们想要的方法   尽管如此。

依赖注入?

  

StructureMap作为我们的Io​​C依赖解析器

除非您使用的所有库都必须一起使用,否则最终会有几个库。

您将使您的服务成为第三方库的代理,或者您的服务将使用第三方库的代理。

但无论如何,代理部分,不应该在同一个库中。如果你这样做,就很难改变第三方库。

如果您选择服务使用第三方库代理的解决方案。由于依赖注入,您可以轻松地将这些代理注入到您的服务中。 如果您更改了第三方库,请更改代理实施并更改注入,并且已完成。

但是,如果您选择将服务作为代理。它几乎相同,但你减少了一层。您的服务实现必须导出到不同的库中。在更改服务时,您还必须更加小心,因为您最终会破坏应用程序中的其他位置。 对于最后一点,拥有服务使用的代理层,对我来说听起来更好。

我还在想。它将有更多我想象的编辑