Java 设计模式 - 组合模式
组合模式介绍
这有点像螺丝 和螺母,通过⼀堆的链接组织出⼀棵结构树。而这种通过把相似对象 ( (也可以称作是方法)组合成⼀组可被调用的结构树对象的设计思路叫做组合模式。
这种设计⽅式可以让你的服务组节点进⾏⾃由组合对外提供服务,例如你有三个原⼦校验功能( A:身份 证 、 B:银⾏卡 、 C:⼿机号 )服务并对外提供调⽤使⽤。有些调⽤⽅需要使⽤AB组合,有些调⽤⽅需要 使⽤到CBA组合,还有⼀些可能只使⽤三者中的⼀个。那么这个时候你就可以使⽤组合模式进⾏构建服 务,对于不同类型的调⽤⽅配置不同的组织关系树,⽽这个树结构你可以配置到数据库中也可以不断的 通过图形界⾯来控制树结构。
所以不同的设计模式⽤在恰当好处的场景可以让代码逻辑⾮常清晰并易于扩展,同时也可以减少团队新 增⼈员对项⽬的学习成本
案例场景模拟
以上是⼀个非常简化版的营销规则 决策树 ,根据 性别 、 年龄 来发放不同类型的优惠券,来刺激消费起 到精准用户户促活的目的
⽤⼀坨坨代码实现这⾥我们举⼀个关于 ifelse 诞⽣的例⼦,介绍⼩姐姐与程序员 之间的 故事 导致的 事故 。
⼯程结构itstack-demo-des ...
MySQL单表访问方法
单表访问方法为了故事的顺利发展,我们先得有个表:
CREATE TABLE single_table ( id INT NOT NULL AUTO_INCREMENT, key1 VARCHAR(100), key2 INT, key3 VARCHAR(100), key_part1 VARCHAR(100), key_part2 VARCHAR(100), key_part3 VARCHAR(100), common_field VARCHAR(100), PRIMARY KEY (id), KEY idx_key1 (key1), UNIQUE KEY idx_key2 (key2), KEY idx_key3 (key3), KEY idx_key_part(key_part1, key_part2, key_part3)) Engine=InnoDB CHARSET=utf8;
我们为这个 single_table 表建立了1个聚簇索引和4个二级索引,分别是:
为 id 列建立的聚簇索引。
为 k ...
MySQL中InnoDB的表空间
InnoDB的表空间表空间 是一个抽象的概念,对于系统表空间来说,对应着文件系统中一个或多个实际文件;对于每个独立表空间来说,对应着文件系统中一个名为 表名.ibd 的实际文件。大家可以把表空间想象成被切分为许许多多个 页 的池子,当我们想为某个表插入一条记录的时候,就从池子中捞出一个对应的页来把数据写进去。
回忆一些旧知识页面类型InnoDB是以页为单位管理存储空间的,我们的聚簇索引(也就是完整的表数据)和其他的二级索引都是以 B+ 树的形式保存到表空间的,而 B+ 树的节点就是数据页。
这个数据页的类型名其实是: FIL_PAGE_INDEX ,除了这种存放索引数据的页面类型之外,InnoDB也为了不同的目的设计了若干种不同类型的页面:
类型名称
十六进制
描述
FIL_PAGE_IBUF_BITMAP
0x0005
Insert Buffer位图
FIL_PAGE_TYPE_SYS
0x0006
系统页
FIL_PAGE_TYPE_TRX_SYS
0x0007
事务系统数据
FIL_PAGE_TYPE_FSP_HDR
0x0008
表空间头部信息
FI ...
DDD(中)
DDD 建模方法四色建模(风暴事件)是整个 DDD 这套软件设计方法中用于工程拆分界限上下文的非常重要的实践手段。通过建模过程快速识别业务领域中的关键事件和核心流程,也是在这个过程中设计出领域对象的,为后面详细设计和代码开发做指导。
可以把整个过程理解为,为工程开发提供面向对象设计,涵盖;领域拆分、界限串联、功能聚合。所以相比Service + 数据模型的贫血开发方式,DDD 前期需要付出更多的设计成本,但对于软件的长周期迭代,这样的好处是非常大的。
1. 建模目的工程的建模的目的是为了我们做工程开发时提供指导方案,就像一栋大楼的设计蓝图一样,也像一个超市中会有不同品类的货架,需要提前规划好。所以你需要在工程开发时所需的各类核心内容,都会在建模中体现,如;分几个包、有哪些核心对象、要串联什么流程、有哪些核心业务要实现、过程中与外部服务的交互。
那么为了达成一个讨论的共识,而不是每个人都有一套的标准和词汇。所以会使用 DDD 提供专门的建模方法和名词进行统一的设计,此外因为 DDD 的统一建模语言,不涉及技术编码,也具有通用性,所以可以在建模过程让产品、研发、测试、架构师等人员一起参与讨 ...
MySQL的B+树索引
B+树索引页和记录的关系示意图如下:
页a、页b、页c … 页n 这些页可以不在物理结构上相连,只要通过双向链表相关联即可。
没有索引的查找先只唠叨搜索条件为对某个列精确匹配的情况,所谓精确匹配,就是搜索条件中用等于 = 连接起的表达式,比如这样:
SELECT [列名列表] FROM 表名 WHERE 列名 = xxx;
在一个页中的查找假设目前表中的记录比较少,所有的记录都可以被存放到一个页中,在查找记录的时候可以根据搜索条件的不同分为两种情况:
以主键为搜索条件
这个查找过程我们已经很熟悉了,可以在 页目录 中使用二分法快速定位到对应的槽,然后再遍历该槽对应分组中的记录即可快速找到指定的记录。
以其他列作为搜索条件
因为在数据页中并没有对非主键列建立所谓的 页目录,所以我们无法通过二分法快速定位相应的 槽 。这种情况下只能从 最小记录 开始依次遍历单链表中的每条记录,然后对比每条记录是不是符合搜索条件。很显然,这种查找的效率是非常低的。
在很多页中查找大部分情况下我们表中存放的记录都是非常多的,需要好多的数据页来存储这些记录。在很多页中查找记录的话可 ...
MySQL的数据目录
MySQL的数据目录数据库和文件系统的关系像 InnoDB 、 MyISAM 这样的存储引擎都是把表存储在文件系统上的。当我们想读取数据的时候,这些存储引擎会从文件系统中把数据读出来返回给我们,当我们想写入数据的时候,这些存储引擎会把这些数据又写回文件系统。
本章就是要唠叨一下 InnoDB 和 MyISAM 这两个存储引擎的数据如何在文件系统中存储的。
MySQL数据目录MySQL服务器程序在启动时会到文件系统的某个目录下加载一些文件,之后在运行过程中产生的数据也都会存储到这个目录下的某些文件中,这个目录就称为 数据目录
数据目录和安装目录的区别我们之前只接触过 MySQL 的安装目录(在安装 MySQL 的时候我们可以自己指定),我们重点强调过这个 安装目录 下非常重要的 bin 目录,它里边存储了许多关于控制客户端程序和服务器程序的命令(许多可执行文件,比如 mysql , mysqld , mysqld_safe 等等等等好几十个)。
数据目录 是用来存储 MySQL 在运行过程中产生的数据,一定要和本章要讨论的 安装目录 区别开
如何确定MySQL中的数据目录到底 MySQ ...
MySQL中InnoDB数据页结构
InnoDB数据页结构数据页:存放我们表中记录的页,官方称这种存放记录的页为索引( INDEX )页,这些表中的记录就是我们日常口中所称的数据,所以也可以称这种存放记录的页为数据页
数据页结构的快速浏览数据页代表的这块 16KB 大小的存储空间可以被划分为多个部分,不同部分有不同的功能,各个部分如图所示:
一个 InnoDB 数据页的存储空间大致被划分成了 7 个部分,有的部分占用的字节数是确定的,有的部分占用的字节数是不确定的。
名称
中文名
占用空间大小
简单描述
File Header
文件头部
38 字节
页的一些通用信息
Page Header
页面头部
56 字节
数据页专有的一些信息
Infimum + Supremum
最小记录和最大记录
26 字节
两个虚拟的行记录
User Records
用户记录
不确定
实际存储的行记录内容
Free Space
空闲空间
不确定
页中尚未使用的空间
Page Directory
页面目录
不确定
页中的某些记录的相对位置
File Trailer
文件尾部
8 字节
校验页是否完整
...
MySqlB+树索引的使用
B+树索引的使用我们必须熟悉下边这些结论:
每个索引都对应一棵 B+ 树, B+ 树分为好多层,最下边一层是叶子节点,其余的是内节点。所有 用户记录都存储在 B+ 树的叶子节点,所有 目录项记录 都存储在内节点。
InnoDB 存储引擎会自动为主键(如果没有它会自动帮我们添加)建立 聚簇索引 ,聚簇索引的叶子节点包含完整的用户记录。
我们可以为自己感兴趣的列建立 二级索引 , 二级索引 的叶子节点包含的用户记录由 索引列 + 主键 组成,所以如果想通过 二级索引 来查找完整的用户记录的话,需要通过 回表 操作,也就是在通过 二级索引找到主键值之后再到 聚簇索引 中查找完整的用户记录。
B+ 树中每层节点都是按照索引列值从小到大的顺序排序而组成了双向链表,而且每个页内的记录(不论是用户记录还是目录项记录)都是按照索引列的值从小到大的顺序而形成了一个单链表。如果是 联合索引 的话,则页面和记录先按照 联合索引 前边的列排序,如果该列值相同,再按照 联合索引 后边的列排序。
通过索引查找记录是从 B+ 树的根节点开始,一层一层向下搜索。由于每个页面都按照索引列的值建立了Page Direc ...
DDD(上)
DDDDDD 既不是 MVC 一样的工程结构,也不能直接等同于微服务架构,更不是一种设计模式。
DDD 是领域驱动设计(Domain-Driven Design)的缩写,这是一种主要软件开发方法,由 Eric Evans 在他的书《领域驱动设计:软件核心复杂性应对之道》(Domain-Driven Design: Tackling Complexity in the Heart of Software)中首次提出。
DDD 主要关注于创建与业务领域紧密相关的软件模型,以确保软件能够准确地解决实际问题。
不同的软件,可以有不同的软件模型,使用DDD创建出最适合的软件模型
核心理念领域模型(Domain Model):领域模型是对特定业务领域知识的精确表述,它包括业务中的实体(Entities)、值对象(Value Objects)、服务(Services)、聚合(Aggregates)、聚合根(Aggregate Roots)等概念。领域模型是DDD的核心,它反映了业务专家的语言和决策。
统一语言(Ubiquitous Language):统一语言是开发团队与业务专家共同使用的语言, ...
MySQL中InnoDB记录结构
InnoDB记录结构MySQL 服务器上负责对表中数据的读取和写入工作的部分是 存储引擎 ,而服务器又支持不同类型的存储引擎。真实数据在不同存储引擎中存放的格式一般是不同的,甚至有的存储引擎比如 Memory 都不用磁盘来存储数据,也就是说关闭服务器后表中的数据就消失了。
InnoDB页简介InnoDB 是一个将表中的数据存储到磁盘上的存储引擎,所以即使关机后重启我们的数据还是存在的。
真正处理数据的过程是发生在内存中的,所以需要把磁盘中的数据加载到内存中。
InnoDB 采取的方式是:将数据划分为若干个页,以页作为磁盘和内存之间交互的基本单位,InnoDB中页的大小一般为 16 KB。也就是在一般情况下,一次最少从磁盘中读取16KB的内容到内存中,一次最少把内存中的16KB内容刷新到磁盘中。
InnoDB行格式我们平时是以记录为单位来向表中插入数据的,这些记录在磁盘上的存放方式也被称为 行格式 或者 记录格式 。
设计 InnoDB 存储引擎的大叔们到现在为止设计了4种不同类型的 行格式 ,分别是 Compact 、 Redundant 、Dynamic 和 Compressed 行 ...