Skip to content

Commit 197b6a6

Browse files
committed
Site updated: 2017-05-09 09:06:13
1 parent 26fa40e commit 197b6a6

File tree

4 files changed

+10
-14
lines changed

4 files changed

+10
-14
lines changed

2017/05/08/命令查询职责分离-CQRS-模式/index.html

+4-6
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@
106106
<meta property="og:image" content="https://www.codeproject.com/KB/architecture/555855/CommandSide.jpg">
107107
<meta property="og:image" content="https://www.codeproject.com/KB/architecture/555855/CQRS.jpg">
108108
<meta property="og:image" content="http://images.cnitblog.com/blog/94031/201408/261851449547571.png">
109-
<meta property="og:updated_time" content="2017-05-08T15:17:28.486Z">
109+
<meta property="og:updated_time" content="2017-05-09T01:05:45.205Z">
110110
<meta name="twitter:card" content="summary">
111111
<meta name="twitter:title" content="命令查询职责分离(CQRS)模式">
112112
<meta name="twitter:description" content="背景和问题在传统的数据管理系统中,两个命令(对数据的更新)和查询(对数据的请求)都是针对单个数据存储库中的同一组实体执行的。 这些实体可以是关系数据库(如SQL Server)中一个或多个表中的行的子集。 通常在这些系统中,所有创建,读取,更新和删除(CRUD)操作都应用于实体的相同表示形式。 例如,通过数据访问层(DAL)从数据存储器检索表示客户的数据传输对象(DTO)并显示在屏幕上。 用户更新">
@@ -456,12 +456,10 @@ <h1 id="解决方案CQRS"><a href="#解决方案CQRS" class="headerlink" title="
456456
<p>使用主流方法的许多应用程序都由读写方面常见的模型组成。拥有相同的读写方式可以导致更为复杂的模型,难以维护和优化。</p>
457457
<p>这两种模式的真正实力就是你可以分开改变状态的方法。在处理性能和调优的情况下,这种分离可能非常方便。您可以从写入端分开优化系统的读取端。写方面被称为域。域包含所有行为。阅读方面专门针对报告需求。</p>
458458
<p>这种模式的另一个好处是在大量应用的情况下。您可以将开发人员拆分为在系统不同方面工作的较小团队(读或写),而不了解对方。例如,在阅读方面工作的开发人员不需要了解域模型。</p>
459-
<p>##查询端(Query side)</p>
460-
<p>这些查询只会包含获取数据的方法。 从架构的角度来看,这些将是返回客户端在屏幕上显示的DTO的所有方法。 DTO通常是域对象的预测。 在某些情况下,这可能是一个非常痛苦的过程,特别是当需要复杂的DTO时。</p>
459+
<h2 id="查询端-Query-side"><a href="#查询端-Query-side" class="headerlink" title="查询端(Query side)"></a>查询端(Query side)</h2><p>这些查询只会包含获取数据的方法。 从架构的角度来看,这些将是返回客户端在屏幕上显示的DTO的所有方法。 DTO通常是域对象的预测。 在某些情况下,这可能是一个非常痛苦的过程,特别是当需要复杂的DTO时。</p>
461460
<p>使用CQRS可以避免这些预测。 相反,可以引入一种新的投资DTO的方法。 您可以绕过域模型,并使用读取层从数据存储中直接获取DTO。 当应用程序正在请求数据时,可以通过单次调用读取层来完成此操作,该层返回包含所有所需数据的单个DTO。<br><img src="https://www.codeproject.com/KB/architecture/555855/QuerySide.jpg" alt="q1"></p>
462461
<p>读取层可以直接连接到数据库(数据模型),而使用存储过程来读取数据并不是个好主意。 与数据源的直接连接通过维护和优化使查询变得非常简单。 非正规化数据是有道理的。 这样做的原因是数据通常被查询是执行域行为的多倍。 这种非规范化可能会提高应用程序的性能。</p>
463-
<p>##命令端(Command side)</p>
464-
<p>由于读取端已被分离,因此域仅专注于处理命令。 现在域对象不再需要暴露内部状态。 存储库除了GetById之外只有几种查询方法。</p>
462+
<h2 id="命令端-Command-side"><a href="#命令端-Command-side" class="headerlink" title="命令端(Command side)"></a>命令端(Command side)</h2><p>由于读取端已被分离,因此域仅专注于处理命令。 现在域对象不再需要暴露内部状态。 存储库除了GetById之外只有几种查询方法。</p>
465463
<p><img src="https://www.codeproject.com/KB/architecture/555855/CommandSide.jpg" alt="CommandSide"></p>
466464
<p>命令由客户端应用程序创建,然后发送到域层。 命令是指示特定实体执行某些操作的消息。 命令命名为DoSomething(例如ChangeName,DeleteOrder …)。 他们指示目标实体做某些可能导致不同结果或失败的事情。 命令由命令处理程序处理。</p>
467465
<h1 id="为什么要使用CQRS?"><a href="#为什么要使用CQRS?" class="headerlink" title="为什么要使用CQRS?"></a>为什么要使用CQRS?</h1><p>从CQRS回退一段时间,将域分为DDD中的有界环境的好处之一是使您能够识别并集中于系统更复杂的部分(有界环境),受到不断变化的业务 规则或提供作为关键业务差异化的功能。<br>只有在提供可识别的业务收益的情况下,才应考虑将CQRS模式应用于特定有限的上下文,而不是因为它是您考虑的默认模式。<br>您可以通过应用CQRS模式获得的最常见的业务优势是增强的可扩展性,简化您的域的复杂方面,提高解决方案的灵活性,以及更好地适应不断变化的业务需求。</p>
@@ -739,7 +737,7 @@ <h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</
739737

740738

741739

742-
<div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#背景和问题"><span class="nav-number">1.</span> <span class="nav-text">背景和问题</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#解决方案CQRS"><span class="nav-number">2.</span> <span class="nav-text">解决方案CQRS</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#CQRS介绍"><span class="nav-number">2.1.</span> <span class="nav-text">CQRS介绍</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#为什么要使用CQRS?"><span class="nav-number">3.</span> <span class="nav-text">为什么要使用CQRS?</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#可扩展性"><span class="nav-number">3.0.1.</span> <span class="nav-text">可扩展性</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#降低复杂性"><span class="nav-number">3.0.2.</span> <span class="nav-text">降低复杂性</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#灵活性"><span class="nav-number">3.0.3.</span> <span class="nav-text">灵活性</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#专注于业务"><span class="nav-number">3.0.4.</span> <span class="nav-text">专注于业务</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#有利于构建基于任务的用户界面"><span class="nav-number">3.0.5.</span> <span class="nav-text">有利于构建基于任务的用户界面</span></a></li></ol></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#什么时候可以考虑CQRS"><span class="nav-number">4.</span> <span class="nav-text">什么时候可以考虑CQRS</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#CQRS的简单实现"><span class="nav-number">5.</span> <span class="nav-text">CQRS的简单实现</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#Query端的实现"><span class="nav-number">5.1.</span> <span class="nav-text">Query端的实现</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Command端实现"><span class="nav-number">5.2.</span> <span class="nav-text">Command端实现</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#总结"><span class="nav-number">6.</span> <span class="nav-text">总结</span></a></li></ol></div>
740+
<div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#背景和问题"><span class="nav-number">1.</span> <span class="nav-text">背景和问题</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#解决方案CQRS"><span class="nav-number">2.</span> <span class="nav-text">解决方案CQRS</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#CQRS介绍"><span class="nav-number">2.1.</span> <span class="nav-text">CQRS介绍</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#查询端-Query-side"><span class="nav-number">2.2.</span> <span class="nav-text">查询端(Query side)</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#命令端-Command-side"><span class="nav-number">2.3.</span> <span class="nav-text">命令端(Command side)</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#为什么要使用CQRS?"><span class="nav-number">3.</span> <span class="nav-text">为什么要使用CQRS?</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#可扩展性"><span class="nav-number">3.0.1.</span> <span class="nav-text">可扩展性</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#降低复杂性"><span class="nav-number">3.0.2.</span> <span class="nav-text">降低复杂性</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#灵活性"><span class="nav-number">3.0.3.</span> <span class="nav-text">灵活性</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#专注于业务"><span class="nav-number">3.0.4.</span> <span class="nav-text">专注于业务</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#有利于构建基于任务的用户界面"><span class="nav-number">3.0.5.</span> <span class="nav-text">有利于构建基于任务的用户界面</span></a></li></ol></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#什么时候可以考虑CQRS"><span class="nav-number">4.</span> <span class="nav-text">什么时候可以考虑CQRS</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#CQRS的简单实现"><span class="nav-number">5.</span> <span class="nav-text">CQRS的简单实现</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#Query端的实现"><span class="nav-number">5.1.</span> <span class="nav-text">Query端的实现</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Command端实现"><span class="nav-number">5.2.</span> <span class="nav-text">Command端实现</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#总结"><span class="nav-number">6.</span> <span class="nav-text">总结</span></a></li></ol></div>
743741

744742

745743
</div>

atom.xml

+4-6
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<link href="/atom.xml" rel="self"/>
66

77
<link href="http://yoursite.com/"/>
8-
<updated>2017-05-08T15:17:28.486Z</updated>
8+
<updated>2017-05-09T01:05:45.205Z</updated>
99
<id>http://yoursite.com/</id>
1010

1111
<author>
@@ -20,7 +20,7 @@
2020
<link href="http://yoursite.com/2017/05/08/%E5%91%BD%E4%BB%A4%E6%9F%A5%E8%AF%A2%E8%81%8C%E8%B4%A3%E5%88%86%E7%A6%BB-CQRS-%E6%A8%A1%E5%BC%8F/"/>
2121
<id>http://yoursite.com/2017/05/08/命令查询职责分离-CQRS-模式/</id>
2222
<published>2017-05-08T13:08:30.000Z</published>
23-
<updated>2017-05-08T15:17:28.486Z</updated>
23+
<updated>2017-05-09T01:05:45.205Z</updated>
2424

2525
<content type="html"><![CDATA[<h1 id="背景和问题"><a href="#背景和问题" class="headerlink" title="背景和问题"></a>背景和问题</h1><p>在传统的数据管理系统中,两个命令(对数据的更新)和查询(对数据的请求)都是针对单个数据存储库中的同一组实体执行的。 这些实体可以是关系数据库(如SQL Server)中一个或多个表中的行的子集。</p>
2626
<p>通常在这些系统中,所有创建,读取,更新和删除(CRUD)操作都应用于实体的相同表示形式。 例如,通过数据访问层(DAL)从数据存储器检索表示客户的数据传输对象(DTO)并显示在屏幕上。 用户更新DTO的某些字段(可能通过数据绑定),然后DTO将由DAL保存回数据存储。 同样的DTO用于读写操作。 该图说明了传统的CRUD架构。</p>
@@ -45,12 +45,10 @@
4545
<p>使用主流方法的许多应用程序都由读写方面常见的模型组成。拥有相同的读写方式可以导致更为复杂的模型,难以维护和优化。</p>
4646
<p>这两种模式的真正实力就是你可以分开改变状态的方法。在处理性能和调优的情况下,这种分离可能非常方便。您可以从写入端分开优化系统的读取端。写方面被称为域。域包含所有行为。阅读方面专门针对报告需求。</p>
4747
<p>这种模式的另一个好处是在大量应用的情况下。您可以将开发人员拆分为在系统不同方面工作的较小团队(读或写),而不了解对方。例如,在阅读方面工作的开发人员不需要了解域模型。</p>
48-
<p>##查询端(Query side)</p>
49-
<p>这些查询只会包含获取数据的方法。 从架构的角度来看,这些将是返回客户端在屏幕上显示的DTO的所有方法。 DTO通常是域对象的预测。 在某些情况下,这可能是一个非常痛苦的过程,特别是当需要复杂的DTO时。</p>
48+
<h2 id="查询端-Query-side"><a href="#查询端-Query-side" class="headerlink" title="查询端(Query side)"></a>查询端(Query side)</h2><p>这些查询只会包含获取数据的方法。 从架构的角度来看,这些将是返回客户端在屏幕上显示的DTO的所有方法。 DTO通常是域对象的预测。 在某些情况下,这可能是一个非常痛苦的过程,特别是当需要复杂的DTO时。</p>
5049
<p>使用CQRS可以避免这些预测。 相反,可以引入一种新的投资DTO的方法。 您可以绕过域模型,并使用读取层从数据存储中直接获取DTO。 当应用程序正在请求数据时,可以通过单次调用读取层来完成此操作,该层返回包含所有所需数据的单个DTO。<br><img src="https://www.codeproject.com/KB/architecture/555855/QuerySide.jpg" alt="q1"></p>
5150
<p>读取层可以直接连接到数据库(数据模型),而使用存储过程来读取数据并不是个好主意。 与数据源的直接连接通过维护和优化使查询变得非常简单。 非正规化数据是有道理的。 这样做的原因是数据通常被查询是执行域行为的多倍。 这种非规范化可能会提高应用程序的性能。</p>
52-
<p>##命令端(Command side)</p>
53-
<p>由于读取端已被分离,因此域仅专注于处理命令。 现在域对象不再需要暴露内部状态。 存储库除了GetById之外只有几种查询方法。</p>
51+
<h2 id="命令端-Command-side"><a href="#命令端-Command-side" class="headerlink" title="命令端(Command side)"></a>命令端(Command side)</h2><p>由于读取端已被分离,因此域仅专注于处理命令。 现在域对象不再需要暴露内部状态。 存储库除了GetById之外只有几种查询方法。</p>
5452
<p><img src="https://www.codeproject.com/KB/architecture/555855/CommandSide.jpg" alt="CommandSide"></p>
5553
<p>命令由客户端应用程序创建,然后发送到域层。 命令是指示特定实体执行某些操作的消息。 命令命名为DoSomething(例如ChangeName,DeleteOrder …)。 他们指示目标实体做某些可能导致不同结果或失败的事情。 命令由命令处理程序处理。</p>
5654
<h1 id="为什么要使用CQRS?"><a href="#为什么要使用CQRS?" class="headerlink" title="为什么要使用CQRS?"></a>为什么要使用CQRS?</h1><p>从CQRS回退一段时间,将域分为DDD中的有界环境的好处之一是使您能够识别并集中于系统更复杂的部分(有界环境),受到不断变化的业务 规则或提供作为关键业务差异化的功能。<br>只有在提供可识别的业务收益的情况下,才应考虑将CQRS模式应用于特定有限的上下文,而不是因为它是您考虑的默认模式。<br>您可以通过应用CQRS模式获得的最常见的业务优势是增强的可扩展性,简化您的域的复杂方面,提高解决方案的灵活性,以及更好地适应不断变化的业务需求。</p>

content.json

+1-1
Large diffs are not rendered by default.

css/main.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -1823,7 +1823,7 @@ pre .javascript .function {
18231823
width: 4px;
18241824
height: 4px;
18251825
border-radius: 50%;
1826-
background: #debf2a;
1826+
background: #82a841;
18271827
}
18281828
.links-of-blogroll {
18291829
font-size: 13px;

0 commit comments

Comments
 (0)