blog-hexo/public/2023/11/06/clp7vphgf000d1yz35bm0f7uw/index.html
2023-11-21 13:12:10 +08:00

456 lines
25 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
领域驱动设计
</title>
<meta name="description" content="">
<meta name="keywords" content="">
<meta name="author" content="Mozzie">
<link rel="canonical" href="https://mozzie.cn/2023/11/06/clp7vphgf000d1yz35bm0f7uw/">
<link rel="icon" type="image/svg" href='data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 7h1a2 2 0 0 1 2 2v.5a.5.5 0 0 0 .5.5a.5.5 0 0 1 .5.5v3a.5.5 0 0 1-.5.5a.5.5 0 0 0-.5.5v.5a2 2 0 0 1-2 2h-2"></path><path d="M8 7H6a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h1"></path><path d="M12 8l-2 4h3l-2 4"></path></g></svg>'>
<link rel="stylesheet" href="/css/c080db9c.css">
<meta name="generator" content="Hexo 6.3.0"></head>
<body id="app">
<!-- 响应式布局按钮 -->
<a class="side-navigation btn-hover btn-hover-bg tip left" data-tip="展开">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24">
<g fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect x="4" y="4" width="16" height="16" rx="2"></rect>
<path d="M9 4v16"></path>
</g>
</svg>
</a>
<aside>
<div>
<link rel="stylesheet" href="/css/5bfc518f.css">
<div class="home-bar">
<a href="/" class="tip" data-tip="首页">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512">
<path
d="M172.2 226.8c-14.6-2.9-28.2 8.9-28.2 23.8V301c0 10.2 7.1 18.4 16.7 22c18.2 6.8 31.3 24.4 31.3 45c0 26.5-21.5 48-48 48s-48-21.5-48-48V120c0-13.3-10.7-24-24-24H24c-13.3 0-24 10.7-24 24v248c0 89.5 82.1 160.2 175 140.7c54.4-11.4 98.3-55.4 109.7-109.7c17.4-82.9-37-157.2-112.5-172.2zM209 0c-9.2-.5-17 6.8-17 16v31.6c0 8.5 6.6 15.5 15 15.9c129.4 7 233.4 112 240.9 241.5c.5 8.4 7.5 15 15.9 15h32.1c9.2 0 16.5-7.8 16-17C503.4 139.8 372.2 8.6 209 0zm.3 96c-9.3-.7-17.3 6.7-17.3 16.1v32.1c0 8.4 6.5 15.3 14.8 15.9c76.8 6.3 138 68.2 144.9 145.2c.8 8.3 7.6 14.7 15.9 14.7h32.2c9.3 0 16.8-8 16.1-17.3c-8.4-110.1-96.5-198.2-206.6-206.7z"
fill="currentColor"></path>
</svg>
<span>Mozzie</span>
</a>
<!-- 切换主题 -->
<a id="toggle-theme" class="tip left" data-tip="切换主题">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512">
<path d="M256 118a22 22 0 0 1-22-22V48a22 22 0 0 1 44 0v48a22 22 0 0 1-22 22z" fill="currentColor"></path>
<path d="M256 486a22 22 0 0 1-22-22v-48a22 22 0 0 1 44 0v48a22 22 0 0 1-22 22z" fill="currentColor"></path>
<path
d="M369.14 164.86a22 22 0 0 1-15.56-37.55l33.94-33.94a22 22 0 0 1 31.11 31.11l-33.94 33.94a21.93 21.93 0 0 1-15.55 6.44z"
fill="currentColor"></path>
<path
d="M108.92 425.08a22 22 0 0 1-15.55-37.56l33.94-33.94a22 22 0 1 1 31.11 31.11l-33.94 33.94a21.94 21.94 0 0 1-15.56 6.45z"
fill="currentColor"></path>
<path d="M464 278h-48a22 22 0 0 1 0-44h48a22 22 0 0 1 0 44z" fill="currentColor"></path>
<path d="M96 278H48a22 22 0 0 1 0-44h48a22 22 0 0 1 0 44z" fill="currentColor"></path>
<path
d="M403.08 425.08a21.94 21.94 0 0 1-15.56-6.45l-33.94-33.94a22 22 0 0 1 31.11-31.11l33.94 33.94a22 22 0 0 1-15.55 37.56z"
fill="currentColor"></path>
<path
d="M142.86 164.86a21.89 21.89 0 0 1-15.55-6.44l-33.94-33.94a22 22 0 0 1 31.11-31.11l33.94 33.94a22 22 0 0 1-15.56 37.55z"
fill="currentColor"></path>
<path d="M256 358a102 102 0 1 1 102-102a102.12 102.12 0 0 1-102 102z" fill="currentColor"></path>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512">
<path
d="M264 480A232 232 0 0 1 32 248c0-94 54-178.28 137.61-214.67a16 16 0 0 1 21.06 21.06C181.07 76.43 176 104.66 176 136c0 110.28 89.72 200 200 200c31.34 0 59.57-5.07 81.61-14.67a16 16 0 0 1 21.06 21.06C442.28 426 358 480 264 480z"
fill="currentColor"></path>
</svg>
</a>
</div>
<script src="/js/ae2a0e7b.js"></script>
<!-- search -->
<link rel="stylesheet" href="/css/82dd7e5a.css">
<form class="search-group">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 20 20">
<g fill="currentColor">
<path d="M8.5 3a5.5 5.5 0 0 1 4.383 8.823l4.147 4.147a.75.75 0 0 1-.976 1.133l-.084-.073l-4.147-4.147A5.5 5.5 0 1 1 8.5 3zm0 1.5a4 4 0 1 0 0 8a4 4 0 0 0 0-8z" fill="currentColor"></path>
</g>
</svg>
<span id="search-input">搜索...</span>
<div class="short-key">
<kbd class="key-cap"><span>Ctrl K</span></kbd>
</div>
</form>
<script>
window.algolia = {
appId: "5DTW808BZ8",
SearchOnlyAPIKey: "27845b245efc8a2853cc0bdc7366ea26"
}
window.search = {
enable: "true"
}
</script>
<script src="/js/b9c2be9c.js"></script>
<!-- navigation -->
<link rel="stylesheet" href="/css/3efc6cb5.css">
<section class="category-nav scrollbar-obtrusive">
<ul><li data-path="timeline">
<a href="/archives">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"> <g fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M12 7v14"></path> <path d="M9 18l3 3l3-3"></path> <circle cx="12" cy="5" r="2"></circle> </g> </svg>
<div class="ellipsis">时间轴</div>
</a>
</li><li data-path="roadmap">
<a href="/roadmap">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"> <g fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M10.5 20.4l-6.9-6.9c-.781-.781-.781-2.219 0-3l6.9-6.9c.781-.781 2.219-.781 3 0l6.9 6.9c.781.781.781 2.219 0 3l-6.9 6.9c-.781.781-2.219.781-3 0z"></path> <path d="M9 14v-2c0-.59.414-1 1-1h5"></path> <path d="M13 9l2 2l-2 2"></path> </g> </svg>
<div class="ellipsis">路线</div>
</a>
</li><li data-path="resume">
<a href="/resume">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"> <g fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M14 3v4a1 1 0 0 0 1 1h4"></path> <path d="M5 8V5a2 2 0 0 1 2-2h7l5 5v11a2 2 0 0 1-2 2h-5"></path> <circle cx="6" cy="14" r="3"></circle> <path d="M4.5 17L3 22l3-1.5L9 22l-1.5-5"></path> </g> </svg>
<div class="ellipsis">简历</div>
</a>
</li></ul>
<p>分类</p>
<ul><li class="">
<a href="/categories/CS/">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 4a2 2 0 0 0-2 2v3a2 3 0 0 1-2 3a2 3 0 0 1 2 3v3a2 2 0 0 0 2 2"></path><path d="M17 4a2 2 0 0 1 2 2v3a2 3 0 0 0 2 3a2 3 0 0 0-2 3v3a2 2 0 0 1-2 2"></path></g></svg>
<div class="ellipsis">
<span>CS</span>
</div>
</a>
</li><li class="">
<a href="/categories/EQ/">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M5.636 5.636a9 9 0 0 1 13.397.747L13.414 12l5.619 5.617A9 9 0 1 1 5.636 5.636z"></path><circle cx="11.5" cy="7.5" r="1" fill="currentColor"></circle></g></svg>
<div class="ellipsis">
<span>EQ</span>
</div>
</a>
</li><li class="">
<a href="/categories/Finance/">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"></circle><path d="M14.8 9A2 2 0 0 0 13 8h-2a2 2 0 0 0 0 4h2a2 2 0 0 1 0 4h-2a2 2 0 0 1-1.8-1"></path><path d="M12 6v2m0 8v2"></path></g></svg>
<div class="ellipsis">
<span>Finance</span>
</div>
</a>
</li><li class="active">
<a href="/categories/Front-End/">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 4l-2 14.5l-6 2l-6-2L4 4z"></path><path d="M7.5 8h3v8l-2-1"></path><path d="M16.5 8H14a.5.5 0 0 0-.5.5v3a.5.5 0 0 0 .5.5h1.423a.5.5 0 0 1 .495.57L15.5 15.5l-2 .5"></path></g></svg>
<div class="ellipsis">
<span>Front-End</span>
</div>
</a>
</li><li class="">
<a href="/categories/Hexo/">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 17v1a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-1"></path><path d="M8 16h8"></path><path d="M8.322 12.582l7.956.836"></path><path d="M8.787 9.168l7.826 1.664"></path><path d="M10.096 5.764l7.608 2.472"></path></g></svg>
<div class="ellipsis">
<span>Hexo</span>
</div>
</a>
</li><li class="">
<a href="/categories/%E8%87%AA%E5%AA%92%E4%BD%93/">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"><path d="M9 12a4 4 0 1 0 4 4V4a5 5 0 0 0 5 5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg>
<div class="ellipsis">
<span>自媒体</span>
</div>
</a>
</li></ul>
</section>
<script src="/js/f8b20eb9.js"></script>
<!-- icp -->
<div class="icp">
<a target="_blank" rel="noopener" href="http://beian.miit.gov.cn/">苏ICP备19008833号-4</a>
</div>
</div>
</aside>
<main>
<link rel="stylesheet" href="/css/e7914205.css">
<div class="post-container">
<div class="content">
<header>
<link rel="stylesheet" href="/css/de5de8fb.css">
<nav class="breadcrumb">
<a href="/" class="home tip btn-hover right" data-tip="首页">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512">
<path d="M172.2 226.8c-14.6-2.9-28.2 8.9-28.2 23.8V301c0 10.2 7.1 18.4 16.7 22c18.2 6.8 31.3 24.4 31.3 45c0 26.5-21.5 48-48 48s-48-21.5-48-48V120c0-13.3-10.7-24-24-24H24c-13.3 0-24 10.7-24 24v248c0 89.5 82.1 160.2 175 140.7c54.4-11.4 98.3-55.4 109.7-109.7c17.4-82.9-37-157.2-112.5-172.2zM209 0c-9.2-.5-17 6.8-17 16v31.6c0 8.5 6.6 15.5 15 15.9c129.4 7 233.4 112 240.9 241.5c.5 8.4 7.5 15 15.9 15h32.1c9.2 0 16.5-7.8 16-17C503.4 139.8 372.2 8.6 209 0zm.3 96c-9.3-.7-17.3 6.7-17.3 16.1v32.1c0 8.4 6.5 15.3 14.8 15.9c76.8 6.3 138 68.2 144.9 145.2c.8 8.3 7.6 14.7 15.9 14.7h32.2c9.3 0 16.8-8 16.1-17.3c-8.4-110.1-96.5-198.2-206.6-206.7z" fill="currentColor"></path>
</svg>
</a>
<em>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 20 20">
<g fill="none">
<path d="M7.733 4.207a.75.75 0 0 1 1.06.026l5.001 5.25a.75.75 0 0 1 0 1.035l-5 5.25a.75.75 0 1 1-1.087-1.034L12.216 10l-4.51-4.734a.75.75 0 0 1 .027-1.06z" fill="currentColor"></path>
</g>
</svg>
</em>
<a href="/categories/Front-End/">
Front-End
</a>
<em>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 20 20">
<g fill="none">
<path d="M7.733 4.207a.75.75 0 0 1 1.06.026l5.001 5.25a.75.75 0 0 1 0 1.035l-5 5.25a.75.75 0 1 1-1.087-1.034L12.216 10l-4.51-4.734a.75.75 0 0 1 .027-1.06z" fill="currentColor"></path>
</g>
</svg>
</em>
<span class="ellipsis">
领域驱动设计
</span>
</nav>
<script src="/js/31d6cfe0.js"></script>
</header>
<main class="scrollbar-obtrusive">
<div class="article-container">
<!-- 文章tags -->
<!-- 渲染文章内容 -->
<article>
<h1>领域驱动设计</h1>
<p class="post-info">更新: 2023-11-06 16:02:39</p>
<h1 id="参考文献"><a href="#参考文献" class="headerlink" title="参考文献"></a>参考文献</h1><ul>
<li><a target="_blank" rel="noopener" href="https://juejin.cn/post/6844903618680881165">蚂蚁金服数据体验技术团队 - 领域驱动设计</a></li>
<li><a target="_blank" rel="noopener" href="https://tech.meituan.com/2017/12/22/ddd-in-practice.html">美团 - 领域驱动设计在互联网业务开发中的实践</a></li>
<li><a target="_blank" rel="noopener" href="https://huhao.dev/posts/61190ae2/#%E9%97%AE%E9%A2%98%E5%AD%90%E5%9F%9F%E8%AF%86%E5%88%AB">领域驱动实战思考</a></li>
<li><a target="_blank" rel="noopener" href="https://www.tangshuang.net/8663.html">基于 DDD 的前端项目架构设计与实战</a></li>
<li><a target="_blank" rel="noopener" href="https://www.tangshuang.net/8212.html">React 语境下前端 DDD 的思考</a></li>
</ul>
<h1 id="架构对比"><a href="#架构对比" class="headerlink" title="架构对比"></a>架构对比</h1><p>从后端视角看,对比传统的三层架构,领域驱动</p>
<ul>
<li><code>充血</code>复用了:领域对外的接口</li>
<li><code>领域服务</code>封装了:领域之间的联系</li>
</ul>
<p>贫血模型-&gt;充血模型,降低了<code>service层</code>的负担,同时保证了业务迭代,<code>entity</code>的独立性</p>
<h2 id="MVC"><a href="#MVC" class="headerlink" title="MVC"></a>MVC</h2><p>从数据库视角、分析实体出发,进行系统的构建</p>
<ul>
<li>DAO 层</li>
<li>Service 层</li>
<li>Controller 层</li>
</ul>
<h2 id="后端-DDD"><a href="#后端-DDD" class="headerlink" title="后端 DDD"></a>后端 DDD</h2><blockquote>
<p>针对基础设施层,也可以考虑加入<code>防腐层</code><code>工厂</code></p>
</blockquote>
<p>一个领域基本四层架构</p>
<ol>
<li>用户层(user interface): 对标 controller对外提供 web 服务、接口</li>
<li>应用层(application): 业务层,定义领域可以解决的问题 <code>domainService</code></li>
<li>领域层(domain): 纯粹的描述业务实体</li>
<li>基础设施层(infra): 持久化层(Builder+repository)</li>
</ol>
<p>同时,领域拆分带来如下两个致命问题</p>
<ul>
<li>领域化(微服务)后,数据库是分开的,导致实体调用链复杂,避免跨库查询</li>
<li>避免分布式事务同步</li>
</ul>
<h2 id="前端-DDD"><a href="#前端-DDD" class="headerlink" title="前端 DDD"></a>前端 DDD</h2><blockquote>
<p>?? 这里存在一个问题api 网关到底要不要挪到前端领域目录下来开发</p>
</blockquote>
<ol>
<li>用户层: web、mobile、mini-program …多端</li>
<li>service: 暴露给 UI 组件的 <code>domainSerivce</code>,组织实体的状态流转</li>
<li>entity: 实体、聚合实体、事件</li>
<li>infra: api 请求、缓存、工具</li>
</ol>
<h2 id="工厂-Factory-x2F-Builder"><a href="#工厂-Factory-x2F-Builder" class="headerlink" title="工厂 Factory &#x2F; Builder"></a>工厂 Factory &#x2F; Builder</h2><ul>
<li>数据库表设计层面,如果要<code>多对多</code>的关系,只能很别扭的设计一个中间表。</li>
<li>实体 A 适合 <code>mongo</code>文档形存储,实体 B 适合<code>mysql</code>关系型存储。对于 <code>Builder</code> 而言,直接在这个领域搓出来 <code>A 和 B</code><code>CRUD</code>的实现方法</li>
</ul>
<h2 id="防腐层-Facade-x2F-Adaptor"><a href="#防腐层-Facade-x2F-Adaptor" class="headerlink" title="防腐层 Facade &#x2F; Adaptor"></a>防腐层 Facade &#x2F; Adaptor</h2><p>也被成为适配器,隔离第三方&#x2F;外部服务,例如场景,用户上传文件到阿里云、腾讯云</p>
<pre class="line-numbers language-javascript" data-language="javascript"><code class="language-javascript"><span class="token keyword">class</span> <span class="token class-name">UserUploadServiceFacade</span> <span class="token keyword">extends</span> <span class="token class-name">UserService</span> <span class="token punctuation">&#123;</span>
<span class="token comment">/**
* 上传
*/</span>
<span class="token keyword">async</span> <span class="token function">upload</span><span class="token punctuation">(</span><span class="token parameter">oss</span><span class="token punctuation">)</span> <span class="token punctuation">&#123;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>oss <span class="token operator">===</span> <span class="token string">"ali"</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token string">"OK"</span><span class="token punctuation">;</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>oss <span class="token operator">===</span> <span class="token string">"tx"</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token string">"FAIL"</span><span class="token punctuation">;</span>
<span class="token punctuation">&#125;</span>
<span class="token punctuation">&#125;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre>
<h1 id="领域模型"><a href="#领域模型" class="headerlink" title="领域模型"></a>领域模型</h1><p>实体的<code>贫血-&gt;充血</code>是一个随着业务发展过程演变的结果,初期业务场景不明确,很难充血,瞎几把充血,纯属找难受。</p>
<p>是否需要引入<code>聚合根(aggregate root)</code>的概念,解决领域内实体独立、平铺关系带来的不方便,这个可能比较看心情</p>
<h2 id="贫血模型-POJO-的问题"><a href="#贫血模型-POJO-的问题" class="headerlink" title="贫血模型(POJO)的问题"></a>贫血模型(POJO)的问题</h2><blockquote>
<p>脱离了业务复杂度谈分层,好比抛开剂量谈毒性</p>
</blockquote>
<p>领域对象里只有<code>get/set</code>方法,所有的业务逻辑都不包含在内,从而造成<code>失忆症</code>,从实体中,无法知道发生了那些业务,需要去 <code>service层</code> 里挨个梳理,一旦业务迭代、<code>service 层</code>直接开始变成屎山</p>
<h2 id="充血模型-amp-amp-领域服务的关系"><a href="#充血模型-amp-amp-领域服务的关系" class="headerlink" title="充血模型 &amp;&amp; 领域服务的关系"></a>充血模型 &amp;&amp; 领域服务的关系</h2><blockquote>
<p>确保领域之间独立的,随着不断的充血,保证领域(实体)是独立发展的</p>
</blockquote>
<p>假定两个 domain(实体)</p>
<ul>
<li>学生: 上课、做作业</li>
<li>老师、全体起立、布置作业</li>
</ul>
<p>假定<code>老师</code>调用<code>全体起立</code>,对应肯定要<code>学生</code>调用<code>上课</code>,这个就是 <code>领域服务(domainService)</code> 需要去处理的,他俩不能建立直接的联系。</p>
<ul>
<li>增加新的业务逻辑:在 <code>domainService</code> 增加新的方法。</li>
<li>调整旧的业务逻辑:修改<code>学生</code><code>老师</code>,内部具体的方法,<code>domainService</code> 完全不需要变化。</li>
</ul>
</article>
<link rel="stylesheet" href="/css/80d65618.css">
<div class="copyright">
<a target="_blank" href="https://mozzie.cn/2023/11/06/clp7vphgf000d1yz35bm0f7uw/">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24">
<g fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M3 19a9 9 0 0 1 9 0a9 9 0 0 1 9 0"></path>
<path d="M3 6a9 9 0 0 1 9 0a9 9 0 0 1 9 0"></path>
<path d="M3 6v13"></path>
<path d="M12 6v13"></path>
<path d="M21 6v13"></path>
</g>
</svg>
<span>领域驱动设计</span>
</a>
<ul>
<li>
<span>作者</span>
<p> Mozzie</p>
</li>
<li>
<span>发布于</span>
<p>2023-11-06</p>
</li>
<li>
<span>许可</span>
<p><a target="_blank" rel="noopener" href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a></p>
</li>
</ul>
</div>
<script src="/js/31d6cfe0.js"></script>
<!-- 评论 -->
<div id="vcomments"></div>
</div>
</main>
</div>
<div class="meta-container">
<div class="toc-wrapper content-dialog">
<p class="catalog">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24">
<g fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M4 6h16"></path>
<path d="M4 12h16"></path>
<path d="M4 18h12"></path>
</g>
</svg>
<span>目录</span>
</p>
<!-- 文章toc -->
<ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE"><span class="toc-number">1.</span> <span class="toc-text">参考文献</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E6%9E%B6%E6%9E%84%E5%AF%B9%E6%AF%94"><span class="toc-number">2.</span> <span class="toc-text">架构对比</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#MVC"><span class="toc-number">2.1.</span> <span class="toc-text">MVC</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%90%8E%E7%AB%AF-DDD"><span class="toc-number">2.2.</span> <span class="toc-text">后端 DDD</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%89%8D%E7%AB%AF-DDD"><span class="toc-number">2.3.</span> <span class="toc-text">前端 DDD</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%B7%A5%E5%8E%82-Factory-x2F-Builder"><span class="toc-number">2.4.</span> <span class="toc-text">工厂 Factory &#x2F; Builder</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E9%98%B2%E8%85%90%E5%B1%82-Facade-x2F-Adaptor"><span class="toc-number">2.5.</span> <span class="toc-text">防腐层 Facade &#x2F; Adaptor</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E9%A2%86%E5%9F%9F%E6%A8%A1%E5%9E%8B"><span class="toc-number">3.</span> <span class="toc-text">领域模型</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%B4%AB%E8%A1%80%E6%A8%A1%E5%9E%8B-POJO-%E7%9A%84%E9%97%AE%E9%A2%98"><span class="toc-number">3.1.</span> <span class="toc-text">贫血模型(POJO)的问题</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%85%E8%A1%80%E6%A8%A1%E5%9E%8B-amp-amp-%E9%A2%86%E5%9F%9F%E6%9C%8D%E5%8A%A1%E7%9A%84%E5%85%B3%E7%B3%BB"><span class="toc-number">3.2.</span> <span class="toc-text">充血模型 &amp;&amp; 领域服务的关系</span></a></li></ol></li></ol>
</div>
</div>
</div>
<script>
window.page = {
use: ''
}
window.katex = {
enable: "",
jsCdn: "//cdn.jsdelivr.net/npm/katex@0.13.18/dist/katex.min.js",
cssCdn: "//cdn.jsdelivr.net/npm/katex@0.13.18/dist/katex.min.css"
}
window.mermaid = {
enable: "",
theme: "",
cdn: "//cdn.jsdelivr.net/npm/mermaid@10.4.0/dist/mermaid.min.js",
}
window.valine = {
enable: "",
appId: 'TisMit6uhflounFqAN3ZGjgq-MdYXbMMI',
appKey: 'CdjirjYdz07U5i62ElsJvXUh',
avatar: 'monsterid',
cdn: '//unpkg.com/valine@latest/dist/Valine.min.js',
serverURLs: '//tismit6u.api.lncldglobal.com'
};
</script>
<script src="/js/d3872ea1.js"></script>
</main>
</body>
<script>
window.i18n = {
"tip-collapse": "折叠",
"tip-expand": "展开",
"text-select": "选择",
"text-move": "移动",
"text-esc": "关闭",
"tip-status-done": "完成",
"tip-status-doing": "进行中",
"tip-status-todo": "待办",
"tip-status-other": "废弃",
"tip-status-default": "默认",
"tip-roadmap-today": "定位今天",
"text-search": "搜索...",
"text-today": "今天",
// month
"January": "一月",
"February": "二月",
"March": "三月",
"April": "四月",
"May": "五月",
"June": "六月",
"July": "七月",
"August": "八月",
"September": "九月",
"October": "十月",
"November": "十一月",
"December": "十二月",
}
</script>
<script src="/js/58c91c4e.js"></script>
</html>