您现在的位置: 首页 > 网站导航收录 > 百科知识百科知识
tpl是啥意思_tplpplh啥意思
架构,命令,应用程序tpl是啥意思_tplpplh啥意思
发布时间:2016-12-08加入收藏来源:互联网点击:
-
CQRS 入门
CQRS 代表 Command/Query Responsibility Segregation,这是一件很棒的事情。这是一种架构设计模式,它允许更高级别的层(例如表示层)与其他层(例如应用层)进行通信 - 例如,表示层内的控制器将调用由应用程序执行的命令和查询层组件。CQRS 与 Clean Domain-Driven Design 完美契合,因为它是一种行为模式:Clean DDD 是什么,CQRS 是如何。
在我深入挖掘之前,我想明确一点,你不需要使用 CQRS 来实现 Clean Architecture 或 Clean DDD 解决方案,但你为什么不使用它呢?为了争论,另一种方法可能是将您的编排逻辑封装在应用程序层服务中,这些服务直接注入您的控制器中。一切都很整洁,并尊重依赖倒置原则。但是,您已经丧失了 CQRS 提供的好处,因为它抽象了跨层边界的组件之间的通信过程本身。CQS 原则指出:
查询系统数据的高级操作不应该产生任何副作用——即修改状态。这些称为查询。查询通过 DTO 将数据返回到表示层。修改系统的高级操作不应返回数据。这些应该会产生副作用,修改系统的状态,然后完成。这些被称为命令。在实践中,命令可能会返回一小部分元数据,例如新创建的实体的 ID,但仅此而已。命令也可能返回 ack/nack 响应。命令执行的另一个结果可能是错误条件,在这种情况下,命令应该抛出异常。CQS 自身CQS 可以直接在 Clean DDD 解决方案中实施。为此,您通常会将控制器方法分解为命令/查询(即写入/读取)操作,并且永远不会违反两者之间的分隔。目的是创建一个基于任务的界面,它处理行为,而不仅仅是保存数据或执行其他 CRUD 操作。请注意:这是 CQS 和 CQRS 与 DDD 相交的地方——操作本身通常会使用您正在使用的有界上下文的普遍语言以业务流程命名. 请注意,这种简单、优雅的设计也促进了单一职责原则,因为每个操作都更具凝聚力,并且更好地对应 UI 操作。这促进了接近用户体验 (UX) 驱动开发的开发过程。
CQS 的反面是我经常看到的反模式:命令和查询之间的零分离。在这种非设计中,没有真正的方法来理解给定操作的副作用是什么,因为总是有一些 Rube Goldberg 逻辑在后台运行。这在已有 10 多年历史的遗留应用程序中很常见,但许多应该更了解的职业开发人员仍然以这种方式构建解决方案。另一种常见的反模式是在控制器(Web API)上公开 CRUD 操作,然后业务逻辑分散在整个应用程序中,例如在 UI 本身中或更糟的是在存储过程中的数据库中。这会产生迷宫般的、脆弱的解决方案,在极其荒谬的程度上违反了开放/封闭原则,
CQRS 是 CQS+命令查询职责分离,是什么?CQRS 接受命令和查询并将它们转换为一流的对象。使用 CQS、基于任务的接口的解决方案可以很容易地重构为 CQRS,因为逻辑分离已经存在。两种模式的最大区别在于 CQS 中的命令/查询是方法;在 CQRS 中,模型. 这里的区别很重要。通过将操作视为模型,您将在应用程序中引入令人难以置信的可扩展。这与 .NET 团队在过去引入任务并行库 (TPL) 时所做的没有什么不同:他们采用了在应用程序中开发异步控制流的繁重过程,并将所有这些抽象为一流的对象,可以独立于依赖它们的代码进行处理。
以下是使用 CQRS 的几个明显好处:
可扩展:对系统的读操作通常比写操作多得多。在 CQRS 下,查询可以分解成自己的堆栈并独立于命令进行缩放。能:您可以构建在紧密耦合模型中不可能实现的优化。简单:一开始,您通过在您的架构中使用它来支付少量的复杂,但随着解决方案的增长以满足业务需求,您可以在路上将其收回。随着时间的推移,它更易于维护并且能够更好地管理复杂。怎么运行的在较高级别上,命令/查询在表示层(在控制器操作内部)中实例化并与应用层通信,然后应用层执行业务编排逻辑并执行您感兴趣的高级任务。
一种方法是将命令/查询参数和处理它们的逻辑都放在同一个对象中。该对象使用依赖注入注入每个控制器或使用某种工厂创建。在命令/查询对象上调用Execute()方法并检索结果。我不喜欢这个。
实现 CQRS 的更好方法是将命令/查询与其处理程序分开,并利用进程内消息传递服务将命令/查询对象分派给它们各自的处理程序。这样做有很多好处,但有两个明显的好处是:
它简化了您的代码,因为您不必编写样板来将命令/查询连接到它们各自的处理程序。您已经在应用程序中创建了一个高级任务执行管道,您可以在其中注入横切关注点,例如错误处理、缓存、日志记录、验证、重试等。这是巨大的。命令CQRS 命令总是以现在命令式命名——例如RegisterEmployeeCommand。命令会改变系统状态并返回简单的 ack/nack 或元数据响应,或者它们会抛出异常。它们与域事件的不同之处在于可以拒绝命令;事件不能。命令通常通过应用层与域层交互。这很重要,因为域层包含所有业务逻辑并负责使系统保持一致状态。构成命令的属应尽可能接近第 3 范式 [Greg Young, CQRS Documents ]。如果你对 1NF/2NF/3NF 之间的区别感兴趣,这篇 Quora 帖子很好地解释了它. 最后,命令通常需要是幂等的。
查询CQRS 查询也以现在时命名,通常以“Get”开头——例如 GetEmployeeListQuery。查询不会改变系统状态,它们只是返回数据,通常以数据传输对象的形式。返回的 DTO 上的属的结构接近于第一范式,因为数据可能会从非规范化的数据库查询中返回,并且返回的 DTO 的结构通常会匹配用户的屏幕或某些可由用户使用的规范模型任何客户。
在他的原始规范中,我研究过的大多数专家都同意这一点,Greg Young 指出大多数时候查询应该绕过域层。让我们进一步解开它。为什么我们要直接从应用层传递到表示层?首先,数据模型比用户输入更可靠,并且假设始终是一致的,因此不需要进行验证的数据库。其次,查询不会改变状态,因此进行这种操作的业务域逻辑没有用处。第三,在系统中读取(查询)将比写入(命令)更频繁地发生,因此它们需要快速高效。
命令和查询的其他注意事项
如 CQS 部分所述,命令和查询都应使用通用语言命名,并表示基于任务的操作,而不是 CRUD。后缀“命令”和“查询”是可选的,因此请自行决定。只需确保您的命名约定直观且一致。“可选”属是一种设计味道,可能表明您的基于任务的操作不够内聚。不要从其他命令/查询调用命令/查询。如果你这样做,这是一个很大的气味。如果您需要在命令逻辑中从数据库中检索数据,那么您应该简单地使用 ORM 或其他方法直接查询数据库。请注意,这是一个典型的例子,其中必须违反某些原则才能维护其他原则。在这种情况下,我们违反了 DRY,以避免危险地将堆栈的两侧耦合在一起并将整个事物变成无法维护的垃圾堆。如果您发现自己在松散耦合和 DRY 之间争论不休,那么松散耦合会胜出。整洁 DDD + CQRS一切都导致了这一点。展望未来,我将使用它作为 Web 应用程序开发的主要架构方法,这也是我在演示应用程序中使用的方法。重申一下,高级架构基于清洁架构原则,在系统的同心层之间具有明确的概念分离。
上一篇:气压结构床和框架结构床的区别(气压结构床和框架结构床的区别)
下一篇:返回列表
相关链接 |
||
网友回复(共有 0 条回复) |