架构:放置不依赖于任何其他服务或存储库组件的服务类的位置

Posted

技术标签:

【中文标题】架构:放置不依赖于任何其他服务或存储库组件的服务类的位置【英文标题】:Architecture: Where to put a service class that does not depend on any other service or repository component 【发布时间】:2013-07-11 01:08:11 【问题描述】:

考虑一个具有存储层(持久性)、服务层(应用程序)和 Web (UI) 层的 Web 应用程序。

考虑一个不是 UI 组件且不依赖于服务或存储库层的组件(即 ExternalProgramExecutor)。

问题是:

此组件是否属于服务层? 这个组件是否属于持久层? 是否应该与这些层分开处理?如果有,这部分架构的名称是什么?

【问题讨论】:

【参考方案1】:

问自己以下问题:

它是否持久化了一些东西? 它是否提供服务? 它所做的这些事情是否与您的应用程序特别相关?

第一个问题的答案应该是否定的,因为您已经告诉我们该组件没有以任何方式与应用程序挂钩。

第二个问题的答案应该是肯定的,因为这是所有优秀软件组件都提供的:某种服务。

但是任何称职的灵活组件都应该在软件应用程序的任何地方都能正常工作,所以真正的问题是:您应该将组件放在哪里,以便最忠实地保留您的 Web 架构?

毕竟,Web 架构只是一种组织机制。如果您想在 The One True Web Architecture Reference™ 中找到答案,您就是 doing it wrong。

【讨论】:

【参考方案2】:

我个人会在@Robert 提出的问题列表中添加另一个问题:

    它是否完全独立于我的应用程序?

对我来说,我通常在我的架构中添加一个新的实用程序/框架组件,我在其中放置完全独立的组件,以后可以在其他应用程序中重用。

【讨论】:

【参考方案3】:

根据DDD,这种服务——似乎可以与“Util/Helper”服务同化——应该在“基础设施层”中(src:InfoQ)

架构

典型的企业应用程序架构包括 以下四个概念层:

用户界面(表示层):负责展示 向用户提供信息并解释用户命令。 应用层:该层协调应用活动。它没有 包含任何业务逻辑。它不保持业务状态 对象,但它可以保存应用程序任务的进度状态。 域层:该层包含有关业务的信息 领域。业务对象的状态保存在这里。的坚持 业务对象及其状态可能委托给 基础设施层。 基础设施层:该层充当 所有其他层的支持库。它提供通信 层之间,实现业务对象的持久化,包含 用户界面层等的支持库。

【讨论】:

【参考方案4】:

我希望它是“基础设施层”的一部分。请看:

http://en.wikipedia.org/wiki/Common_layers_in_an_information_system_logical_architecture

http://www.bennadel.com/blog/2385-Application-Services-vs-Infrastructure-Services-vs-Domain-Services.htm

谢谢。

【讨论】:

【参考方案5】:

鉴于您的问题的限制,我想问一下您的独立组件的目的是什么?它主要是围绕某些数据的外观(这将使其成为您的持久层的一部分),还是它是应用程序(您的应用程序层)的域或业务逻辑或工作流的一部分?像外部任务执行器之类的东西,我倾向于认为它是您的应用程序层的一部分。

【讨论】:

【参考方案6】:

从概念上讲,“ExternalProgramExecutor”看起来像一个服务,所以它属于服务层。

进入服务层的细节,有两种可能:

    “ExternalProgramExecutor”服务与其他服务具有相同的性质,因此它是服务层的另一个“要点”, 服务与其他服务有很大的不同,它是服务层的另一个“块”。

这种析取保留了更实用的观点(实现):

    服务依赖于相同的功能(相同的 UI,相同的持久性访问):它应该与服务层的其他部分集成,以使用它们的 API... 服务本质上是独立的:这是一个机会,不要创建不必要的依赖项,独立开发它。

【讨论】:

【参考方案7】:

我倾向于将服务视为您的域模型上的接口,因为听起来这种关系不存在,所以从这个意义上说它不像服务。

您的持久层介导与您的数据存储的通信,但听起来这个组件在那里也没什么可做的。

那么它属于哪一层呢?它真的需要属于一个吗?通过提出这些问题,听起来您已经在花时间正确地组织您的对象。如果您有一个无关组件,您可以:

A) 放到最常用的层

B) 将其放入自己的程序集中,不再担心标记它:)

【讨论】:

【参考方案8】:

多层(软件)架构使用不同的层来分配应用程序的职责,因此我们有:

    职责分离。 工作流程一目了然。 能够以最少的工作量副作用替换层实现。

从第 3 点开始,如果更改“ExternalProgramExecutor”不需要对其他层进行任何更改。我想这本身就值得一层。 我在一个具有类似目的的项目中使用了一个名为“Ext”的层。

如果更改需要任何更改,请将其添加到需要修改的层。

希望对你有帮助。

【讨论】:

【参考方案9】:

好吧,ExternalProgramExecutor 是一个独立的服务,因为您的应用程序将其用作外部组件。

显然,如果您不打算将该组件的source code 作为应用程序项目的一部分,您就不能将该服务放入您的应用程序中。因此,您实际上将在项目中的该服务/组件上拥有一个Gateway。为了使其成为SOLID,您的网关将是抽象,而您的问题是在哪里您应该从哪里引用该抽象网关。

答案完全取决于 ExternalProgramExecutor(以及网关)提供什么样的功能,以及您的项目如何使用该功能。从应用程序的顶层到底层(DAL -> ... -> UI),而抽象功能不是该层的一部分。找到正确的层后,在该层使用网关,底层在运行时不应该知道具体网关的存在。

【讨论】:

以上是关于架构:放置不依赖于任何其他服务或存储库组件的服务类的位置的主要内容,如果未能解决你的问题,请参考以下文章

清晰架构(Clean Architecture)的Go微服务: 依赖注入(Dependency Injection)

云小课|帮您高效快速上传组件至私有依赖库

[架构设计] 组件和模块的区别

微服务架构: 微服务间的共享的管理

微服务架构下组件管理规范

分布式系统中数据存储方案实践