Skip to content

Commit 79ad773

Browse files
committed
feat: rename 编程模式's md file; improve their format;
1 parent 0c9f457 commit 79ad773

File tree

8 files changed

+701
-741
lines changed

8 files changed

+701
-741
lines changed

doc/模板.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
## 补充说明
6464
## 通用UML
6565
<!-- ## 分析角色 -->
66-
## 角色之间的关系
66+
**角色之间的关系**
6767
## 角色的抽象代码
6868
## 遵循的设计原则在UML中的体现
6969

packages/ECS模式/article.md renamed to packages/ECS模式/ECS模式.md

Lines changed: 85 additions & 93 deletions
Large diffs are not rendered by default.

packages/依赖隔离模式/article.md renamed to packages/依赖隔离模式/依赖隔离模式.md

Lines changed: 41 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
2-
31
# 编辑器使用引擎创建场景
42

53
## 需求
@@ -13,19 +11,23 @@
1311

1412

1513
## 给出UML
14+
**领域模型**
1615

1716

1817
![领域模型图](./story_before/UML.png)
1918

20-
总体来看,分为用户、编辑器、引擎这三个部分
19+
总体来看,领域模型分为用户、编辑器、引擎这三个部分
2120

2221
我们看下用户这个部分:
22+
2323
Client是用户
2424

2525
我们看下编辑器这个部分:
26+
2627
Editor是编辑器
2728

2829
我们看下引擎这个部分:
30+
2931
Three.js是Three.js引擎
3032

3133

@@ -80,6 +82,7 @@ Editor引入Three.js引擎,并在createScene函数中调用它来创建场景
8082
- Editor改为引入Babylon.js引擎,并修改Editor中与引擎相关的代码
8183

8284
## 给出UML
85+
**领域模型**
8386

8487

8588
![领域模型图](./story_after/UML.png)
@@ -101,7 +104,8 @@ Editor引入Three.js引擎,并在createScene函数中调用它来创建场景
101104

102105
Client代码跟之前一样,故省略
103106

104-
我们看下Editor的代码:
107+
我们看下Editor的代码
108+
105109
### Editor的代码
106110

107111
Editor
@@ -123,25 +127,26 @@ Editor改为引入Babylon.js引擎,并修改createScene函数中与引擎相
123127

124128
## 提出问题
125129

126-
- 替换引擎的成本太高
130+
- 替换引擎的成本太高
127131
替换引擎需要修改Editor中所有与引擎相关代码,成本太高了。有没有办法能在不修改Editor代码的情况下实现替换引擎呢?
128132

129133

130134
# 使用依赖隔离模式来改进
131135

132136
## 概述解决方案
133137

134-
- 解除依赖
138+
- 解除依赖
135139
只要解除Editor和引擎的依赖,把替换引擎的逻辑隔离出去就可以实现
136140

137141

138142

139143
## 给出UML
140144

145+
**领域模型**
141146

142147
![领域模型图](./story_improve/UML.png)
143148

144-
总体来看,分为用户、编辑器、引擎、容器这四个部分
149+
总体来看,领域模型分为用户、编辑器、引擎、容器这四个部分
145150

146151
我们看下用户这个部分:
147152

@@ -171,14 +176,15 @@ Three.js是Three.js引擎
171176

172177
DependencyContainer是保存注入的Engine接口实现的容器,提供操作它的get和set函数
173178

174-
**依赖关系**
179+
<!-- **依赖关系** -->
180+
我们来看下依赖关系:
175181

176182
Client通过依赖注入的方式注入Engine接口的一个实现(BabylonImplement或者ThreeImplement),从而使Editor能够调用它来创建场景
177183

178184

179185
## 结合UML图,描述如何具体地解决问题
180186

181-
- 替换Three.js为Babylon.js引擎现在不再影响Editor了,只需要增加BabylonImplement,并让Client从注入ThreeImplement改为注入BabylonImplement即可
187+
- 替换Three.js为Babylon.js引擎现在不再影响Editor了,只需要增加BabylonImplement,并让Client从注入ThreeImplement改为注入BabylonImplement即可
182188
因为Editor只依赖Engine接口,所以Engine接口的实现的变化不会影响Editor
183189

184190

@@ -226,7 +232,7 @@ Editor增加了injectDependencies函数,它将Client注入的Engine接口实
226232

227233
createScene函数通过DependencyContainer获得注入的Engine接口实现,它的类型是Engine接口,用来创建场景
228234

229-
值得注意的是:
235+
值得注意的是:
230236
Editor只依赖Engine接口,没有依赖Engine接口的实现
231237

232238

@@ -337,61 +343,62 @@ BabylonImplement的implement函数使用了Babylon.js引擎,返回了Engine接
337343

338344
## 通用UML
339345

346+
**领域模型**
340347

341348
![领域模型图](./role_abstract/UML.png)
342349

343350

344351
<!-- ## 分析角色 -->
345352

346-
我们来看看模式的相关角色:
353+
<!-- 我们来看看模式的相关角色: -->
347354

348-
总体来看,分为用户、系统、外部依赖、容器这四个部分
355+
总体来看,领域模型分为用户、系统、外部依赖、容器这四个部分
349356

350357

351358
我们看下用户这个部分:
352359

353-
- Client
360+
- Client
354361
该角色是用户,通过依赖注入的方式注入DependencyImplement
355362

356363
我们看下系统这个部分:
357364

358-
- System
365+
- System
359366
该角色使用了外部依赖,它只知道外部依赖的接口(Dependency)而不知道具体实现(DependencyImplement)
360367

361368

362369
我们看下外部依赖这个部分:
363370

364-
- Dependency
371+
- Dependency
365372
该角色是外部依赖的接口
366-
- DependencyImplement
373+
- DependencyImplement
367374
该角色是Dependency的实现
368-
- DependencyLibrary
375+
- DependencyLibrary
369376
该角色是一个库
370377

371378

372379
我们看下容器这个部分:
373380

374-
- DependencyContainer
381+
- DependencyContainer
375382
该角色是保存注入的DependencyImplement的容器,提供操作它的get和set函数
376383

377384

378-
## 角色之间的关系
385+
**角色之间的关系**
379386

380-
- 可以有多个Dependency
387+
- 可以有多个Dependency
381388
如除了Engine以外,还可以有File、Server等Dependency,其中每个Dependency对应一个外部依赖
382389

383-
- 一个Dependency可以有多个DependencyImplement来实现
390+
- 一个Dependency可以有多个DependencyImplement来实现
384391
如Engine的实现除了有ThreeImplement,还可以有BabylonImplement等实现
385392

386393

387394
- Client可以依赖注入多个Dependency接口的实现。其中,对于一个Dependency接口而言,Client只依赖注入实现它的一个DependencyImplement
388395

389396
- 因为System可以使用多个Dependency接口,所以它们是一对多的关系
390397

391-
- 一个DependencyImplement一般只使用一个DependencyLibrary,但也可以使用多个DependencyLibrary
398+
- 一个DependencyImplement一般只使用一个DependencyLibrary,但也可以使用多个DependencyLibrary
392399
如可以增加实现Engine接口的ThreeAndBabylonImplement,它同时使用Three.js和Babylon.js这两个DependencyLibrary来创建场景
393400

394-
- 只有一个DependencyContainer容器,它保存了所有注入的DependencyImplement,为每个DependencyImplement都提供了get和set函数
401+
- 只有一个DependencyContainer容器,它保存了所有注入的DependencyImplement,为每个DependencyImplement都提供了get和set函数
395402

396403

397404

@@ -500,9 +507,9 @@ export let api1 = function () {
500507

501508
依赖隔离模式主要遵循下面的设计原则:
502509

503-
- 依赖倒置原则
510+
- 依赖倒置原则
504511
系统依赖于外部依赖的抽象(Dependency)而不是外部依赖的细节(DependencyImplement和DependencyLibrary),从而外部依赖的细节的变化不会影响系统
505-
- 开闭原则
512+
- 开闭原则
506513
要隔离更多的外部依赖,只需要增加对应的Dependency、DependencyImplement和DependencyLibrary,以及DependencyContainer增加对应的闭包变量和get、set函数即可,无需修改System;要替换外部依赖的实现,只需要对它的Dependency增加更多的DependencyImplement,然后Client改为注入新的DependencyImplement即可,无需修改System;要修改已有的外部依赖(如升级版本),只需要修改DependencyImplement和DependencyLibrary即可,无需修改System
507514

508515
依赖隔离模式也应用了“依赖注入”、“控制反转”的思想
@@ -513,11 +520,11 @@ export let api1 = function () {
513520

514521
## 优点
515522

516-
- 提高系统的稳定性
523+
- 提高系统的稳定性
517524
外部依赖的变化不会影响系统
518-
- 提高系统的扩展性
525+
- 提高系统的扩展性
519526
可以任意替换外部依赖而不影响系统
520-
- 提高系统的可维护性
527+
- 提高系统的可维护性
521528
系统与外部依赖解耦,便于维护
522529

523530

@@ -538,23 +545,19 @@ export let api1 = function () {
538545

539546
- 编辑器使用的引擎、UI库等第三方库需要替换
540547

541-
- 编辑器使用的引擎、UI库等第三方库的版本需要升级
542-
548+
- 编辑器使用的引擎、UI库等第三方库的版本需要升级
543549
如需要升级编辑器使用的Three.js引擎的版本,只需要升级作为DependencyLibrary的Three.js,并修改ThreeImplement,使其使用升级后的Three.js即可
544550

545-
- 需要增加编辑器使用的引擎、UI库等第三方库
546-
551+
- 需要增加编辑器使用的引擎、UI库等第三方库
547552
如需要让编辑器在已使用Three.js引擎的基础上增加使用Babylon.js引擎,则只需要加入ThreeAndBabylonImplement,让它同时使用Three.js和Babylon.js这两个DependencyLibrary
548553

549554

550555

551556

552557
## 注意事项
553558

554-
- Dependency要足够抽象,才不至于在修改或增加DependencyImplement时需要修改Dependency,从而影响System
555-
556-
当然,在开发阶段难免考虑不足,如一开始只有一个DependencyImplement时,Dependency往往只会考虑这个DependencyImplement。这导致在增加实现该Dependency的其它DependencyImplement时发现需要修改Dependency,使其更加抽象,这样才能容纳因增加更多的DependencyImplement而带来的变化
557-
559+
- Dependency要足够抽象,才不至于在修改或增加DependencyImplement时需要修改Dependency,从而影响System
560+
当然,在开发阶段难免考虑不足,如一开始只有一个DependencyImplement时,Dependency往往只会考虑这个DependencyImplement。这导致在增加实现该Dependency的其它DependencyImplement时发现需要修改Dependency,使其更加抽象,这样才能容纳因增加更多的DependencyImplement而带来的变化
558561
因此,我们可以允许在开发阶段修改Dependency,但是在发布前则确保Dependency已经足够抽象和稳定
559562

560563
<!-- - 有多少个Dependency接口,DependencyContainer就有多少个get和set函数 -->
@@ -572,7 +575,7 @@ export let api1 = function () {
572575

573576
- 划分4个层:外部依赖层、应用服务层、领域服务层、领域模型层,其中前者为上层,前者依赖后者
574577
<!-- - 外部依赖都位于外部依赖层,它们是按照依赖隔离模式设计的,在运行时由用户注入 -->
575-
- 将系统的所有外部依赖都使用依赖隔离模式来隔离出去,为每个外部依赖抽象一个Dependency接口。将DependencyImplement放到最上层的外部依赖层,将Dependency放到最下层的领域模型层。
578+
- 将系统的所有外部依赖都使用依赖隔离模式来隔离出去,为每个外部依赖抽象一个Dependency接口。将DependencyImplement放到最上层的外部依赖层,将Dependency放到最下层的领域模型层。
576579
这是因为DependencyImplement容易变化,所以将其放到最上层,这样它的变化不会影响其它层;而Dependency非常稳定不易变化,且被领域模型依赖,所以将其放到领域模型层
577580
<!-- 其它三层不依赖外部依赖层,而是依赖领域模型层中的Application Core(具体就是依赖Dependency) -->
578581
- 运用领域驱动设计来设计系统,将系统的核心逻辑建模为领域模型,将其放到领域模型层
@@ -637,7 +640,7 @@ export let api1 = function () {
637640

638641
### 满足各种修改外部依赖的用户需求
639642

640-
我遇到过这种问题:3D应用开发完成后,交给3个外部用户使用。用了一段时间后,这3个用户提出了不同的修改外部依赖的要求:第一个用户想要升级3D应用依赖的引擎A,第二个用户想要替换引擎A为引擎B,第三个用户想要同时使用引擎B和升级后的引擎A。
643+
我遇到过这种问题:3D应用开发完成后,交给3个外部用户使用。用了一段时间后,这3个用户提出了不同的修改外部依赖的要求:第一个用户想要升级3D应用依赖的引擎A,第二个用户想要替换引擎A为引擎B,第三个用户想要同时使用引擎B和升级后的引擎A。
641644
如果3D应用没有使用依赖隔离模式,而是使用调用引擎这个外部依赖的话,我们就需要将交付的代码修改为3个版本,分别满足3个用户的需求。交付的3个版本的代码如下:
642645

643646
- 使用了升级A的3D应用代码

0 commit comments

Comments
 (0)