learn.lianglianglee.com/专栏/DDD实战课/结束语 所谓高手,就是跨过坑和大海.md.html
2022-05-11 19:04:14 +08:00

457 lines
18 KiB
HTML
Raw Permalink 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>
<!-- saved from url=(0046)https://kaiiiz.github.io/hexo-theme-book-demo/ -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
<link rel="icon" href="/static/favicon.png">
<title>结束语 所谓高手,就是跨过坑和大海.md.html</title>
<!-- Spectre.css framework -->
<link rel="stylesheet" href="/static/index.css">
<!-- theme css & js -->
<meta name="generator" content="Hexo 4.2.0">
</head>
<body>
<div class="book-container">
<div class="book-sidebar">
<div class="book-brand">
<a href="/">
<img src="/static/favicon.png">
<span>技术文章摘抄</span>
</a>
</div>
<div class="book-menu uncollapsible">
<ul class="uncollapsible">
<li><a href="/" class="current-tab">首页</a></li>
</ul>
<ul class="uncollapsible">
<li><a href="../">上一级</a></li>
</ul>
<ul class="uncollapsible">
<li>
<a href="/专栏/DDD实战课/00 开篇词 学好了DDD你能做什么.md.html">00 开篇词 学好了DDD你能做什么.md.html</a>
</li>
<li>
<a href="/专栏/DDD实战课/01 领域驱动设计微服务设计为什么要选择DDD.md.html">01 领域驱动设计微服务设计为什么要选择DDD.md.html</a>
</li>
<li>
<a href="/专栏/DDD实战课/02 领域、子域、核心域、通用域和支撑域:傻傻分不清?.md.html">02 领域、子域、核心域、通用域和支撑域:傻傻分不清?.md.html</a>
</li>
<li>
<a href="/专栏/DDD实战课/03 限界上下文:定义领域边界的利器">03 限界上下文:定义领域边界的利器</a>
</li>
<li>
<a href="/专栏/DDD实战课/04 实体和值对象:从领域模型的基础单元看系统设计.md.html">04 实体和值对象:从领域模型的基础单元看系统设计.md.html</a>
</li>
<li>
<a href="/专栏/DDD实战课/05 聚合和聚合根:怎样设计聚合?.md.html">05 聚合和聚合根:怎样设计聚合?.md.html</a>
</li>
<li>
<a href="/专栏/DDD实战课/06 领域事件:解耦微服务的关键.md.html">06 领域事件:解耦微服务的关键.md.html</a>
</li>
<li>
<a href="/专栏/DDD实战课/07 DDD分层架构有效降低层与层之间的依赖.md.html">07 DDD分层架构有效降低层与层之间的依赖.md.html</a>
</li>
<li>
<a href="/专栏/DDD实战课/08 微服务架构模型:几种常见模型的对比和分析.md.html">08 微服务架构模型:几种常见模型的对比和分析.md.html</a>
</li>
<li>
<a href="/专栏/DDD实战课/09 中台:数字转型后到底应该共享什么?.md.html">09 中台:数字转型后到底应该共享什么?.md.html</a>
</li>
<li>
<a href="/专栏/DDD实战课/10 DDD、中台和微服务它们是如何协作的.md.html">10 DDD、中台和微服务它们是如何协作的.md.html</a>
</li>
<li>
<a href="/专栏/DDD实战课/11 DDD实践如何用DDD重构中台业务模型.md.html">11 DDD实践如何用DDD重构中台业务模型.md.html</a>
</li>
<li>
<a href="/专栏/DDD实战课/12 领域建模:如何用事件风暴构建领域模型?.md.html">12 领域建模:如何用事件风暴构建领域模型?.md.html</a>
</li>
<li>
<a href="/专栏/DDD实战课/13 代码模型如何使用DDD设计微服务代码模型.md.html">13 代码模型如何使用DDD设计微服务代码模型.md.html</a>
</li>
<li>
<a href="/专栏/DDD实战课/14 代码模型(下):如何保证领域模型与代码模型的一致性?.md.html">14 代码模型(下):如何保证领域模型与代码模型的一致性?.md.html</a>
</li>
<li>
<a href="/专栏/DDD实战课/15 边界:微服务的各种边界在架构演进中的作用?.md.html">15 边界:微服务的各种边界在架构演进中的作用?.md.html</a>
</li>
<li>
<a href="/专栏/DDD实战课/16 视图:如何实现服务和数据在微服务各层的协作?.md.html">16 视图:如何实现服务和数据在微服务各层的协作?.md.html</a>
</li>
<li>
<a href="/专栏/DDD实战课/17 从后端到前端:微服务后,前端如何设计?.md.html">17 从后端到前端:微服务后,前端如何设计?.md.html</a>
</li>
<li>
<a href="/专栏/DDD实战课/18 知识点串讲基于DDD的微服务设计实例.md.html">18 知识点串讲基于DDD的微服务设计实例.md.html</a>
</li>
<li>
<a href="/专栏/DDD实战课/19 总结(一):微服务设计和拆分要坚持哪些原则?.md.html">19 总结(一):微服务设计和拆分要坚持哪些原则?.md.html</a>
</li>
<li>
<a href="/专栏/DDD实战课/20 总结分布式架构关键设计10问.md.html">20 总结分布式架构关键设计10问.md.html</a>
</li>
<li>
<a href="/专栏/DDD实战课/答疑有关3个典型问题的讲解.md.html">答疑有关3个典型问题的讲解.md.html</a>
</li>
<li>
<a class="current-tab" href="/专栏/DDD实战课/结束语 所谓高手,就是跨过坑和大海.md.html">结束语 所谓高手,就是跨过坑和大海.md.html</a>
</li>
</ul>
</div>
</div>
<div class="sidebar-toggle" onclick="sidebar_toggle()" onmouseover="add_inner()" onmouseleave="remove_inner()">
<div class="sidebar-toggle-inner"></div>
</div>
<script>
function add_inner() {
let inner = document.querySelector('.sidebar-toggle-inner')
inner.classList.add('show')
}
function remove_inner() {
let inner = document.querySelector('.sidebar-toggle-inner')
inner.classList.remove('show')
}
function sidebar_toggle() {
let sidebar_toggle = document.querySelector('.sidebar-toggle')
let sidebar = document.querySelector('.book-sidebar')
let content = document.querySelector('.off-canvas-content')
if (sidebar_toggle.classList.contains('extend')) { // show
sidebar_toggle.classList.remove('extend')
sidebar.classList.remove('hide')
content.classList.remove('extend')
} else { // hide
sidebar_toggle.classList.add('extend')
sidebar.classList.add('hide')
content.classList.add('extend')
}
}
function open_sidebar() {
let sidebar = document.querySelector('.book-sidebar')
let overlay = document.querySelector('.off-canvas-overlay')
sidebar.classList.add('show')
overlay.classList.add('show')
}
function hide_canvas() {
let sidebar = document.querySelector('.book-sidebar')
let overlay = document.querySelector('.off-canvas-overlay')
sidebar.classList.remove('show')
overlay.classList.remove('show')
}
</script>
<div class="off-canvas-content">
<div class="columns">
<div class="column col-12 col-lg-12">
<div class="book-navbar">
<!-- For Responsive Layout -->
<header class="navbar">
<section class="navbar-section">
<a onclick="open_sidebar()">
<i class="icon icon-menu"></i>
</a>
</section>
</header>
</div>
<div class="book-content" style="max-width: 960px; margin: 0 auto;
overflow-x: auto;
overflow-y: hidden;">
<div class="book-post">
<p id="tip" align="center"></p>
<div><h1>结束语 所谓高手,就是跨过坑和大海</h1>
<p>你好,我是欧创新。</p>
<p>这是本专栏的最后一讲了,非常感谢你这两个月的陪伴,也非常感谢你的意见和建议。加上前期的专栏筹备,前前后后也有半年了,这半年其实也是自我提升的过程,通过专栏,我将原来不成体系的经验、方法和设计思想,整理成了中台和微服务设计的系统的理论和知识体系。</p>
<p>在撰写专栏时,我站在架构师的角度,尽力将我在实践过程中的经验、思考和体会,以及原创案例等全面详细地呈现给你。希望能够对你的 DDD 实践和架构设计有所帮助,也希望你能快速成长为具有企业级战略视角的架构师和 DDD 设计大师。</p>
<p>那说到成长,相信我们每个人的轨迹都是独特的,但有一点,你一定和我有同样的体会。那就是“所谓高手,就是跨过坑和大海!”每一步都是积累,每一步都是经验,每一步都算数!所以啊,在本专栏的最后,我还是要分享一些干货给你,也是我曾经踩过的一些坑。</p>
<p>很多人接触 DDD可能是从 DDD 战术设计开始的,因此不知道如何开始 DDD 实践。这个专栏开启后,咱们就可以从领域建模开始了。有了领域模型,我们就可以划分出合理的微服务的逻辑和物理边界;也是因为有了它,我们才能识别出微服务内各关键对象,并建立它们之间的依赖关系,然后开始微服务的设计和开发。</p>
<p>而很多 DDD 和微服务设计的书籍,大多侧重于讲述 DDD 战术设计或者一些通用的微服务设计模式。这些书籍大多没有告诉我们:如何从业务领域开始,去构建领域模型?如何用 DDD 的思想,来指导中台和微服务设计?如何将领域模型作为输入,来设计和拆分微服务?如何将 DDD 知识体系组合起来,应用到中台和微服务的设计和开发中…</p>
<p>这也是本专栏与这些书籍的不同点。当然,我并不是说它们不好,只是各有侧重。在真正实践的时候,强大的知识基础自然也是刚需,你可以把专栏和书籍结合起来学习,从而发挥最大效能。</p>
<p><strong>下面是我推荐的几本书,这些内容是可以和本专栏互补的,如果你有意愿进一步学习 DDD它们是非常好的学习资料。</strong></p>
<p><img src="assets/8a90eb7bb3a80baa917cef282b7ff042.jpg" alt="img" /></p>
<p>DDD 是一个相对复杂的方法体系,它与传统的软件开发模式或者流程存在一定的差异。在实践 DDD 时,你可能会遇到一些困难。企业需要在研发模式上有一定的调整,同时项目团队也需要提升 DDD 的设计和技术能力,培养适合 DDD 成长的土壤。拔高一点看的话,我觉得你可能会遇到这样三个大坑,下面我来说一说我的看法。</p>
<h2>1. 业务专家或领域专家的问题</h2>
<p>传统企业中业务人员是需求的主要提出者,但由于部门墙,他们很少会参与到软件设计和开发过程中。如果研发模式不调整,你不要奢望业务人员会主动加入到项目团队中,一起来完成领域建模。没有业务人员的参与,是不是就会觉得没有领域专家,不能领域建模了呢?其实并不是这样的。</p>
<p>对于成熟业务的领域建模,我们可以从团队需求人员或者经验丰富的设计或开发人员中,挑选出能够深刻理解业务内涵和业务管理要求的人员,担任领域专家完成领域建模。对于同时熟悉业务和面向对象设计的项目人员,这种设计经验尤其重要,他们可以利用面向对象的设计经验,更深刻地理解和识别出领域模型的领域对象和业务行为,有助于推进领域模型的设计。</p>
<p>而对于新的创业企业,他们面对的是从来没人做过的全新的业务和领域,没有任何可借鉴的经验,更不要提什么领域专家。对于这种情况,就需要团队一起经过更多次更细致的事件风暴,才能建立领域模型。当然建模过程离不开产品愿景分析,这个过程是确定和统一系统建设目标以及项目的核心竞争力在哪里。这种初创业务的领域模型往往需要经过多次迭代才能成型,不要奢望一次就可以建立一个完美的领域模型。</p>
<h2>2. 团队 DDD 的理念和技术能力问题</h2>
<p>完成领域建模和微服务设计后,就要投入开发和测试了。这时你可能会发现一些开发人员,并不理解 DDD 设计方法,不知道什么是聚合、分层以及边界?也不知道服务的依赖以及层与层之间的职责边界是什么?</p>
<p>这样容易出现设计很精妙,而开发很糟糕的状况。遇到这种情况,除了要在项目团队普及 DDD 的知识和设计理念外,你还要让所有的项目成员尽早地参与到领域建模中,事件风暴的过程除了统一团队语言外,还可以让团队成员提前了解领域模型、设计要点和注意事项。</p>
<h2>3. DDD 设计原则问题</h2>
<p>DDD 基于各种考虑,有很多的设计原则,也用到了很多的设计模式。条条框框多了,很多人可能就会被束缚住,总是担心或犹豫这是不是原汁原味的 DDD。其实我们不必追求极致的 DDD这样做反而会导致过度设计增加开发复杂度和项目成本。</p>
<p>DDD 的设计原则或模式,是考虑了很多具体场景或者前提的。有的是为了解耦,如仓储服务、边界以及分层,有的则是为了保证数据一致性,如聚合根管理等。在理解了这些设计原则的根本原因后,有些场景你就可以灵活把握设计方法了,你可以突破一些原则,不必受限于条条框框,大胆选择最合适的方法。</p>
<p><strong>以上就是我对这三个问题的理解了。</strong></p>
<p>用好 DDD 的关键,首先要领悟 DDD 的核心设计思想和理念了解它为什么适合微服务架构然后慢慢体会、消化、吸收和实践。DDD 体系虽然复杂,但也是有矩可循的,照着样例多做几个事件风暴,完成领域建模和微服务设计,体会 DDD 的整个设计过程。相信你很快就能领悟到 DDD 的核心设计理念了,这样就可以做到收放自如,趟出一条适合自己的 DDD 实践之路。</p>
<p>好了,到了该说再见的时候了。再次感谢你的陪伴,期待再相遇!愿我们都能跨过坑和大海,开辟出一片广阔新天地!</p>
</div>
</div>
<div>
<div style="float: left">
<a href="/专栏/DDD实战课/答疑有关3个典型问题的讲解.md.html">上一页</a>
</div>
</div>
</div>
</div>
</div>
</div>
<a class="off-canvas-overlay" onclick="hide_canvas()"></a>
</div>
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v652eace1692a40cfa3763df669d7439c1639079717194" integrity="sha512-Gi7xpJR8tSkrpF7aordPZQlW2DLtzUlZcumS8dMQjwDHEnw9I7ZLyiOj/6tZStRBGtGgN6ceN6cMH8z7etPGlw==" data-cf-beacon='{"rayId":"70996f0acdd63d60","version":"2021.12.0","r":1,"token":"1f5d475227ce4f0089a7cff1ab17c0f5","si":100}' crossorigin="anonymous"></script>
</body>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-NPSEEVD756"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'G-NPSEEVD756');
var path = window.location.pathname
var cookie = getCookie("lastPath");
console.log(path)
if (path.replace("/", "") === "") {
if (cookie.replace("/", "") !== "") {
console.log(cookie)
document.getElementById("tip").innerHTML = "<a href='" + cookie + "'>跳转到上次进度</a>"
}
} else {
setCookie("lastPath", path)
}
function setCookie(cname, cvalue) {
var d = new Date();
d.setTime(d.getTime() + (180 * 24 * 60 * 60 * 1000));
var expires = "expires=" + d.toGMTString();
document.cookie = cname + "=" + cvalue + "; " + expires + ";path = /";
}
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i].trim();
if (c.indexOf(name) === 0) return c.substring(name.length, c.length);
}
return "";
}
</script>
</html>