领域驱动设计(Domain-Driven Design)

领域驱动设计(DDD,Domain-Driven Design)是帮助开发大型系统的原则和模式的集合。DDD 更像一种方法论,指导我们开发大型的系统。

软件系统设计理念经历了 POP(面向过程编程)、OOP(面向对象编程)、DDD(领域驱动设计) 的转变。POP 设计,通过构建函数、分层,划分模块等方式,分解软件系统的复杂度。OOP 把软件的设计从功能维度提升到实体维度,进一步分解软件系统的复杂度,并以一种更易于理解的方式来组织软件系统。

随着软件系统规模的不断扩大,面临着实体爆炸的问题,在一个单一的逻辑范畴内,处理所有的实体,到了极其复杂的程度。DDD 通过把系统从需求维度划分为不同的领域,每个领域进行单独的设计,域之间通过暴露接口来进行协作。

核心概念

contexts

构成要素

  • 实体(Entity)
  • 值对象(Value Objects)
  • 领域服务(Domain Service)
  • 聚合根(Aggregate Root)
  • 工厂(Factories)
  • 仓储(Repository)

Bounded Context

contexts

参考

plantuml 类图

声明元素

1
2
3
4
5
6
7
8
9
10
11
12
13
@startuml
abstract abstract
abstract class "abstract class"
annotation annotation
circle circle
() circle_short_form
class class
diamond diamond
<> diamond_short_form
entity entity
enum enum
interface interface
@enduml

定义关系

关系 符号
扩展(Extension) <|–
组合(Conposition) *–
聚合(Aggregation) o–

示例

1
2
3
4
5
6
7
8
9
10
11
@startuml
class Dummy {
String data
void methods()
}

class Flight {
flightNumber : Integer
departureTime : Date
}
@enduml

SQL

创建表

语法

1
2
3
4
5
6
CREATE TABLE 表名称 (
列名称1 数据类型,
列名称2 数据类型,
列名称3 数据类型,
....
)

示例

1
2
3
4
5
6
7
8
9
CREATE TABLE `syscontroldb`.`sys_user` (
`id` INT(11) NOT NULL COMMENT '用户DI,系统唯一标识',
`userName` VARCHAR(45) NOT NULL COMMENT '用户名,系统唯一',
`password` VARCHAR(45) NOT NULL COMMENT '用户密码,加密',
`customerID` INT(11) NOT NULL COMMENT '所属用户代码',
`tel` VARCHAR(20) NULL COMMENT '电话号码',
`status` INT(3) NOT NULL COMMENT '用户状态,0正常,1注销,2暂停' DEFAULT 1,
PRIMARY KEY (`id`))
COMMENT = '系统用户表';

Select

1
SELECT * from <table> WHERE <field>=<value>

Add

1
INSERT INTO <table> (<field>, <field>, ...) VALUES (<value>, <value>, ...)

Updata

1
UPDATE <table> SET <field>=<value>,<field>=<value> WHERE <field>=<value>

Join

left

1
2
# 别名
SELECT a.id, b.id FROM zj_classify a left join zj_classify b on b.parent = a.id ;

自驾游 - 乌兰察布

物品

证件

  • [ ] 身份证
  • [ ] 驾驶证

衣物

  • [ ] 5摄氏度外套
  • [ ] 帽子

洗护

  • [ ] 洗面奶
  • [ ] 牙刷、牙刷、毛巾
  • [ ] 防晒、护肤
  • [ ] 驱虫、风油精

娱乐

  • [ ] 桌游
  • [ ] 自拍杆
  • [ ] 手机、电脑、平板、充电线、充电宝

饮食

  • [ ] 矿泉水
  • [ ] 自嗨锅
  • [ ] 零食

药品

  • [ ] 腹泻
  • [ ] 感冒
  • [ ] 发烧
  • [ ] 止痛片
  • [ ] 跌打损伤
  • [ ] 创伤贴、纱布

其他

  • [ ] 抽纸、湿巾
  • [ ] 雨伞、一次性雨衣

prometheus 查询语句

分组求和

1
2
3
4
5
# 语法
sum by(cluster)(rate(...))

# 对应用 <app> 最进一分钟的counter标签值为 <search> 的数据,以 cluster 为分组进行求和
sum by(cluster)(rate(<app>_timer_count{counter="search"}[1m]))

一段时间内总量

1
2
3
4
5
 # 3天内请求总量
sum(increase(requst_count{counter="...",...}[3d]))

# sum_over_time
sum(sum_over_time(request_count{...}[1d]))

QPS

1
2
3
4
5
6
7
# 单机
rate(request_count{label='value',...}[1m])
irate(request_count{label='value',...}[1m])
# irate 比 rate 更能凸显瞬时值, 或者说 rate 比 irate 更平滑

# 所有机器
sum(rate(request_count{label='value',...}[1m]))

Label Replace

语法

1
2
3
4
5
6
7
8
label_replace(query, "dest_label", "replacement", "src_label", "regex")

# 说明
query: 查询语句
dest_label: 替换后的 label 名称
replacement: 替换后的 label value 表达式, 支持正则查询后的分组
src_label: 需要替换的 label
regex: 需要替换的 label value 正则表达式

示例

1
2
3
4
5
6
7
8
label_replace(up{job="node-exporter"}, "foo", "bar-$1", "job", "node-(.+)")
# 效果
up{foo="bar-exporter"}
# 说明
$1 = exporter

# 使用 time range
rate(label_replace(up{job="node-exporter"}, "foo", "bar-$1", "job", "node-(.+)")[1m:])

ON…GROUP_LEFT

示例

统计分可用区的服务可用性。

1
2
sum(rate(label_replace(no_fail_request{job=~"${cluster}"}, "private_ip_address", "$1", "instance", "(.*):8000$")[1m:]) * on (private_ip_address) group_left(zone) agent_status{instance_state="running",region="${cluster}"}) by (zone) / 
sum(rate(label_replace(total_request{job=~"${cluster}"}, "private_ip_address", "$1", "instance", "(.*):8000$")[1m:]) * on (private_ip_address) group_left(zone) agent_status{instance_state="running",region="${cluster}"}) by (zone)

过滤不为 0

1
2
avg(metric_name{] != 0) by (region)  # 对值为 0 的指标不进行 avg 计算
avg(metric_name{]) by (region) != 0 # 对值为 0 的结果不进行展示

英语常识

地址

格式

级别 英文 示例
Room Room 602
Vallage Huaxi Vallage
No.* No.12
1
2
3
4
5
6
7
8
9
10
11
12
X室 Room X
X 村 *** Vallage,如华西村 Huaxi Vallage.
X号 No. X
X单元 Unit X
X号楼 Building No. X
X街 X Street
X路 X Road
X区 X District
X县 X County
X镇 X Town
X市 X City
X省 X Province

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
宝山区良港村37号403室
Room 403, No. 37, Lianggang Residential Quarter, BaoShan District

虹口区西康南路125弄34号201室
Room 201, No. 34, Lane 125, XiKang Road(South), HongKou District

四川省成都市花都大道100号世纪光花小区3023号
No.3023,Shijiguanghua Residential Quater,Huadu Avenue,Chengdu City, Sichuan Province

河南省南阳市中州路42号 李有财 473004
Li Youcai
Room 42
Zhongzhou Road, Nanyang City
Henan Prov. China 473004

473000河南南阳市八一路272号特钢公司 李有财
Li Youcai
Special Steel Corp.
No. 272, Bayi Road, Nanyang City
Henan Prov. China 473000

nc

传送文件

1
2
3
4
5
6
7
8
# receiver
$ nc -l -p {port} > something.tar.gz < /dev/null
# sender
$ cat something.tar.gz | nc {server-ip} {port}

# example
nc -l -p 12345 > something.tar.gz < /dev/null
cat something.zip | nc 127.0.0.1 12345