DDD简介

domain-driven design 领域驱动设计,缩写DDD。它是一种根据实际持续演化的业务,进行分析与拆分以达到建立低耦合高内聚的软件设计方法。

它与传统的 data-driven design有很大的不同。传统的data-driven design开发人员是了解需求背景后,先设计数据库表,再写业务逻辑,业务边界和划分完全凭实际开发人员的判断,并没有一个指导方法。

domain-driven design需要开发人员先了解业务背景,然后根据业务思考领域,确定领域边界和能力后,再根据业务进行领域内的能力设计,数据表和存储可以再领域设计完成之后再进行。

domain-driven design是一种软件设计指导方法论,按照这个方法论,开发人员可以设计出扩展性和维护性很好的软件架构。按照这种方法论设计出来的软件架构可以满足业务的不断演化。

当业务很复杂时,开发人员往往会陷入不知如何设计系统架构,软件架构需要满足当前业务和也要满足未来业务扩展和变更。DDD思想可以帮助开发人员解决这个难题。

什么是算法复杂度

算法(Algorithm): 解决软件问题的一组步骤。从两个维度衡量算法的好坏:时间复杂度、空间复杂度。

  • 时间复杂度:描述算法运行的时间。T(n) = O(f(n))它表示随着输入大小 n 的增大,算法执行需要的时间的增长速度可以用 f(n) 来描述。
  • 空间复杂度:描述算法运行所需要的存储空间大小。S(n)=O(f(n)) 它表示随着输入大小 n 的增大,算法执行需要的空间可以用 f(n)来描述。

什么是Scrum

目的

Scrum 快速开发和持续交付、维护复杂产品的敏捷框架。它定义了敏捷开发中的团队结构、研发过程和关键事件。

Scrum的核心目的是快速的开发和交付产品给客户,并保持产品的灵活性。

它的设计过程中并未提到如何保证产品的质量,这个很让人困惑。对于一个刚起步的团队,最大的挑战应该是产品的质量和产品方向的正确性。而不是快速的开发和交付产品。

后端设计分层

POJO(Plain Ordinary Java Object)简单的Java对象。它指的是:那些没有继承任何类、也没有实现任何接口,更没有被其它框架侵入的java对象。

POJO的所有属性都是私有的,对外提供只提供的setget方法,并且可以被序列化。DO/DTO/BO/VO都属于POJO

常用的web 应用分层格式:

7906797-4c1a0b0cb533792d

Rollup.js配置

rollup.js JavaScript 模块打包器,相比webpack配置更简单轻量。适合library使用的打包工具。

它的特点:

  1. 只想快速配置开发个小工具
  2. 要用ES6+语法开发
  3. 代码清洁,清理无用代码(tree-shaking)

它输出各种模块规范:AMDCommonJSUMDIIFE

微前端的前世今生

qiankun 是目前较成熟可以开箱即用的实现微前端的框架。它主要特点有:

  1. 简单 - 任意 js 框架均可使用。微应用接入像使用接入一个 iframe 系统一样简单,但实际不是 iframe。
  2. 完备 - 几乎包含所有构建微前端系统时所需要的基本能力,如 样式隔离、js 沙箱、预加载等。
  3. 生产可用 - 已在蚂蚁内外经受过足够大量的线上系统的考验及打磨,健壮性值得信赖。

qiankun2.0 提供了两种接入微应用的方式:基于路由配置、手动加载微应用。

RxJS

RxJS 是 Javascript 世界中实现响应式编程工具库,它使得在 JS 中处理复杂的数据流变得简单和易于维护。

响应式编程反应式编程(英语:Reactive programming)是一种面向数据和变化传播的声明式编程范式。这意味着可以在编程语言中很方便地表达静态或动态的数据流,而相关的计算模型会自动将变化的值通过数据流进行传播。 - wikipedia

InversifyJS

InversifyJS 是一个轻量的 (4KB) 控制反转容器 (IoC),可用于编写 TypeScript 和 JavaScript 应用。 它使用类构造函数去定义和注入它的依赖。

因为 ES6 之后 JavaScript 支持用 Class 方式用于OOP编程,但要做好 OOP 设计是很困难的,InversifyJS 它能帮助 JavaScript 开发者,写出出色的面向对象设计的代码。

InversifyJS 的设计哲学:

  • 允许 JavaScript 开发人员编写遵循 SOLID 原则的代码
  • 促进并鼓励遵守最佳的 OOP 编程和 IoC 实践
  • 尽可能少的运行时开销
  • 提供艺术编程体验和生态

浏览器跨页面通讯

同源策略是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。

**同源定义: ** 两个页面的Protocol(协议)Port(端口)host(域名)相同

例如:http://www.aaa.com/dir/page.html 协议: ** http://端口: 80(默认)域名:** www.aaa.com

1
2
3
4
5
"http://www.aaa.com/dir/other.html" :同源
"http://aaa.com/dir/other.html": 不同源(域名不同)
"http://v2.www.aaa.com/dir/other.html": 不同源(域名不同)
"http://www.aaa.com:8081/dir/other.html": 不同源(端口不同)
"https://www.aaa.com:8081/dir/other.html": 不同源(协议不同)

JS Memory Leak And V8 Garbage Collection

内存泄漏(Memory Leak):程序中不会再被使用到的内存且无法被浏览器 GC (Garbage Collection)回收。

内存泄漏可能导致诸如应用程序速度降低,崩溃,高延迟等问题。

⚠️本文内容都是基于 Chrome浏览器 V8 JS 解析引擎。

如何导致 内存泄漏

一句话简单总结内存泄漏:应该存在时间很短的Object,但是被无意中引用导致无法被销毁。

ReflectMetadata

**反射(Reflect)**一般指那些用来检验(inspect)其他代码的代码,部分使用场景:依赖注入/运行时类型断言/测试。

当JS应用变复杂时,需要使用一些(IoC容器)或特性(运行时类型断言)来处理复杂度,而由于JS中不存在反射的特性很难做到这一点。

一个反射API应允许在运行时检验一个未知对象,获取其不限于名称、类型、接口、参数等信息。

在JS中可以使用Object.getOwnPropertyDescriptor()Object.keys()来获取实体的信息,但还是需要反射去实现更强大的开发工具。目前在TS中可以使用reflect-metadata来实现反射特性,同时这个库是作为metadata reflection API的polyfill,可参考相关提案

TS装饰器

装饰器(Decorators)是一种特殊的声明,可附加在类、方法、访问器、属性、参数声明上。

装饰器(Decorators)可以通过非侵入方式增强方法访问器属性参数的能力。可以将业务逻辑代码和特殊能力和服务的代码分割开来,保证代码的灵活性和扩展性,合理的利用装饰器可以极大的提高我们的开发效率。

注意: 同样的滥用装饰器也会使代码本身逻辑变得扑朔迷离,如果确定一段代码不会在其他地方用到,或者一个函数的核心逻辑就是这些代码,那么就没有必要将它取出来作为一个装饰器来存在。

为什么需要装饰器

例如: 我们想记录一个方法执行的耗时

没有使用装饰器方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Model1 {
getData() {
let start = new Date().valueOf()
try {
// 此处省略获取数据的逻辑
return [{
id: 1,
name: 'Niko'
}, {
id: 2,
name: 'Bellic'
}]
} finally {
let end = new Date().valueOf()
console.log(`start: ${start} end: ${end} consume: ${end - start}`)
}
}
}

// start: XXX end: XXX consume: XXX
console.log(new Model1().getData()) // [ { id: 1, name: 'Niko'}, { id: 2, name: 'Bellic' } ]
// start: XXX end: XXX consume: XXX
console.log(Model1.prototype.getData()) // [ { id: 1, name: 'Niko'}, { id: 2, name: 'Bellic' } ]

在上面代码中,getData方法中包含了一些非业务的逻辑代码。而这些代码还是不可复用的。

使用装饰器的方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function log(target, descriptor, descriptor) {
Object.defineProperty(target, key, {
...descriptor,
value: function (...arg) {
let start = new Date().valueOf()
try {
return descriptor.value.apply(this, arg) // 调用之前的函数
} finally {
let end = new Date().valueOf()
console.log(`start: ${start} end: ${end} consume: ${end - start}`)
}
}
})
}

class Model1 {
@log
getData() {
return [{
id: 1,
name: 'Niko'
}, {
id: 2,
name: 'Bellic'
}]
}
}

上面的代码中,我们将增加了一个log用来记录方法执行的时间。通过装饰器我们将业务逻辑和非业务逻辑代码分割开来。

Java collections framework

Java集合(collections)框架提供了一组接口和类,以实现各种数据结构和算法。例如,集合框架的LinkedList类提供了双向链接列表数据结构的实现。

Java异常处理

异常是程序执行期间发生的意外事件。它影响程序指令的流程,这可能导致程序异常终止。

出于多种原因可能会发生异常。他们之中有一些是:

  • 无效的用户输入
  • 设备故障
  • 网络连接丢失
  • 物理限制(磁盘内存不足)
  • 代码错误
  • 打开一个不可用的文件

Java异常层次结构

这是Java中异常层次结构的简化图:

Throwable类是层次结构中的根类。请注意,层次结构分为两个分支:ErrorException

Java的OOP

Java是一个严格的面相对象(OOP)语言,面向对象方法的核心概念是将复杂的问题分解为较小的对象.具体的对象应该尽量做聚合抽象.得到共同的抽象父类.

一个对象有两个部分组成:状态和行为. 以一个高级点的自行车🚴‍♀️为例子:

  1. 状态: 速度、档位
  2. 行为: 换档、刹车

## 类和实例对象

类(Class)是对象(Object)的蓝图,在我们创建一个Object之前我们应该先定义一个Class.

我们可以将Class视为房子的草图(原型)。它包含有关地板,门,窗户等的所有详细信息。基于这些描述,我们建造了房屋。房子是Object

Java基础语法

Java是一门通用性编程语言,其特征包括但不限于面对对象、跨平台、多线程、高性能等等.Java的最大的特点是跨平台,利用及其稳定的Java虚拟机(Java Virtual Machine)同样的源代码可能在任何平台运行。这不仅仅提高了软件的可移植性,也简化了开发者的工作。

Java是一门设计优良的编程语言,它是一门完全的面向对象编程语言,面向对象编程是一种重要的编程思想,对于构建复杂的系统有很大的积极作用.

AST懵逼入门

AST(Abstract Syntax Tree)抽象语法树,或简称语法树(Syntax tree). 是源代码语法结构的一种抽象表示. 它以树状的形式表现编程语言的语法结构, 树上的每一个节点都表示源代码中的一种结构.

1
2
3
4
5
6
while b ≠ 0
if a > b
a := a − b
else
b := b − a
return a

Docker入门

docker是一个开源的应用容器引擎,基于Go语言开发并遵循apache2.0协议开源.docker可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的linux服务器,也可以实现虚拟化。