系统架构设计整洁之道.docx

上传人:b****2 文档编号:3264541 上传时间:2023-05-05 格式:DOCX 页数:11 大小:1.19MB
下载 相关 举报
系统架构设计整洁之道.docx_第1页
第1页 / 共11页
系统架构设计整洁之道.docx_第2页
第2页 / 共11页
系统架构设计整洁之道.docx_第3页
第3页 / 共11页
系统架构设计整洁之道.docx_第4页
第4页 / 共11页
系统架构设计整洁之道.docx_第5页
第5页 / 共11页
系统架构设计整洁之道.docx_第6页
第6页 / 共11页
系统架构设计整洁之道.docx_第7页
第7页 / 共11页
系统架构设计整洁之道.docx_第8页
第8页 / 共11页
系统架构设计整洁之道.docx_第9页
第9页 / 共11页
系统架构设计整洁之道.docx_第10页
第10页 / 共11页
系统架构设计整洁之道.docx_第11页
第11页 / 共11页
亲,该文档总共11页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

系统架构设计整洁之道.docx

《系统架构设计整洁之道.docx》由会员分享,可在线阅读,更多相关《系统架构设计整洁之道.docx(11页珍藏版)》请在冰点文库上搜索。

系统架构设计整洁之道.docx

系统架构设计整洁之道

系统架构设计整洁之道

 

一、架构设计的目标

1.用最少的人力成本满足构建和维护该系统的需求

2.衡量指标

a.工程师团队规模

b.代码总行数

c.代码变更行数

二、软件系统的价值

1.行为价值

a.按需求文档编写代码

b.可用性

i.功能性bug

ii.性能

iii.稳定性

c.紧急,但是并不总是重要

2.架构价值

a.当需求变更时,所需的软件变更必须简单方便

b.变更实施的难度应该和变更的范畴(scope)成等比,而与变更的具体形状(shape)无关

c.不紧急

三、编程范式

1.目的:

设置限制,告诉我们不可以做什么

2.现有范式

a.结构化编程

i.目的:

对控制权的直接转移进行了限制和规范

ii.内容:

可以用顺序结构、分支结构、循环结构这三种结构构造出任何结构;限制goto的使用。

iii.意义:

用代码把一些已证明的结构串联起来,就可以推导出整个程序的正确性。

实际上没有办法证明每个程序段是正确的,只能证伪,如果所有的基本单元都无法证伪,那么整个就是无法证伪的,那目前就是正确的。

iv.延伸:

物理学与数学的区别,物理学的基本公式都是没有办法证明的,只能证伪,所以物理学是实验科学,没有一个公式是完全靠得住的,只是目前靠得住。

数学的基本公式都是可以证明的。

b.面向对象编程

i.目的:

对程序控制权的间接转移进行了限制和规范

ii.定义

A.封装:

只暴露部分函数,数据则完全不暴露

B.继承

C.多态:

其实只是函数指针的一种应用,通过接口和实现,抽象类和继承,替代了函数指针的使用

iii.意义:

函数指针,是跨越组件边界的方法,是组件独立部署的基础,依赖反转的基础。

依赖反转指的是让依赖与控制流向相反。

c.函数式编程

i.目的:

对赋值进行了限制和规范

ii.趋势:

如果有足够大的存储量和计算量,应用程序可以用事件溯源的方式,用完全不可变的函数式编程,只通过事务记录,从头计算状态

iii.意义:

所有的竞争问题、死锁问题、并发问题都是由可变变量导致的。

iv.应用:

通过将状态修改的部分和不需要修改的部分分隔成单独的组件,提高系统的稳定性和效率

四、设计原则

1.意义

a.如何将数据和函数组织成类

b.如何将类链接起来成为组件和程序

2.开闭原则(OCP)

a.目标:

让系统易于扩展,同时限制每次修改所影响的范围

b.实现:

划分组件,并将组件间依赖关系按层次结构进行组织

c.本原则是我们进行架构设计的主导原则

3.单一职责原则(SRP)

a.目标:

指导类、组件拆分

b.定义

i.任何一个软件模块,都应该有且只有一个被修改的原因

ii.“被修改的原因”指系统的用户或所有者

c.痛点

i.同样的一块逻辑,如果服务于两个价值主体,因为一个价值主体而修改,那么第二个价值主体期望的功能将被影响。

比如CTO和COO都要员工的工时,分别用于计算薪酬和汇报,两者的计算方式可能目前是相同的,一方有了更改,另一方就bug了

ii.如果一块代码,归属于两个团队共同维护,就会有代码合并问题

4.里氏替换原则(LSP)

a.目标:

指导接口与实现方式【边界处理】

b.内容

i.不是实现了同一个接口,它们的行为就是一致并可以互相替换,长方形正方形是典型的案例

ii.如果两个组件,替换之后需要分别做特别的设置,那就说明抽象得还不足够,会引入许多if-else,可以配置清单等方式消除

5.接口隔离原则(ISP)

a.目标:

指导接口的定义【边界处理】

b.内容

i.不依赖任何不需要的组件、类、方法

ii.如果不同的用户分别使用一个大接口的几个不同方法,那么应该把这个大接口拆分为针对这些用户的小接口

6.依赖反转原则(DIP)

a.目标:

指导依赖方向【依赖】

b.内容:

组件间跨越边界的源码依赖的方向永远与控制流的方向相反

五、组件

1.定义:

是软件的部署单元,是整个软件系统可以独立完成部署的最小实体

2.拆分原则

a.REP:

复用、发布等同原则

i.内容:

软件复用的最小粒度应等同于其发布的最小粒度

b.CCP:

共同闭包原则

i.内容:

将为了相同目的而同时修改的类放在同一个组件中,是SRP原则在组件层面的描述

ii.执行

A.对大部分应用程序而言,可维护性的重要性远远大于可复用性

B.因为一个原因需要做修改,这个修改最好在同一个组件中,如果分散在多个组件中,那么开发、提交、部署的成本都会上升

c.CRP:

共同复用原则

i.内容:

不要强迫一个组件依赖它不需要的东西,是ISP原则在组件层面的描述

d.张力图

i.

ii.架构设计中有许多矛盾,研发性和复用性的矛盾,而研发性本身又有粘性(CCP)和排斥性(CRP)的矛盾

iii.架构师做的往往是在这个张力图中找到一个最符合现在需要的点,而这个平衡也是不断变化的,根据项目的规模、迭代的节奏等

3.依赖原则

a.无依赖环原则

i.互相依赖的组件,实际上组成了一个大组件,这三个组件要一起发布、一起做单元测试

ii.通过依赖反转原则可以解依赖环

b.稳定依赖原则

i.内容

A.依赖必须指向更稳定的方向,接口是最稳定的

B.组件的稳定性,指的是组件的变更困难度,影响因素有很多,比如代码的体量大小、复杂度、清晰度等,但是最重要的一个因素就是依赖的数量——让组件难于修改的一个最直接的办法就是让很多其它组件依赖与它

C.组件的稳定性和它的变更频繁度没有直接的关联。

或者说,稳定性可以分为价值(需求)的稳定性,和组件自身的稳定性

ii.定量指标:

不稳定性(I)=出向依赖数量/(入向依赖数量+出现依赖数量)

iii.方法:

可以通过抽接口,共同依赖接口的方式,修正违反稳定依赖的地方

c.稳定抽象原则

i.内容

A.一个组件的抽象化程度应该与其稳定性保持一致

B.为了防止高阶架构设计和高阶策略难以修改,通常抽象出稳定的接口或抽象类。

越稳定的库就应该越抽象,这样它的稳定性就不会影响它的扩展性

ii.定量描述

A.抽象程度(A)=组件中抽象类和接口的数量/组件中类的数量

B.将不稳定性和抽象程度分别作为横轴和纵轴,画一个二维的图,(0,1)-(1,0)连线就是主序列线。

靠近(0,0)的区域是痛苦区,改动成本很大,但是又很具体。

靠近(1,1)的是无用区,非常抽象,但是没有别的组件依赖它,改动成本很小,通常是废弃的。

C.离主序列线的距离D=|A+I-1|,可以定量化的衡量一个组件的健康程度。

在D满足期望的条件下,越靠近(0,1)和(1,0)越好

六、封装方式

1.经典的封装方式

a.按层封装

i.问题

A.无法展现具体的业务领域

B.不能防止跨层调用。

通常情况下,绕过业务逻辑是不合理的,尤其是要控制权限时

b.按功能封装

c.端口和适配器

d.按组件封装

2.组织形式与封装的区别

a.如果没有封装和隐藏功能,采用任何架构风格都没有区别

七、软件架构

1.目的

a.终极目的:

最大化程序员的生产力,最小化系统的总运营成本

b.细化目标:

支撑软件系统的全生命周期,让系统便于理解、易于修改、方便维护、轻松部署

2.方针

a.尽可能长时间地保留尽可能多的可选项

i.选项指的是无关紧要的细节设计

ii.选项例子

A.具体选用哪个存储方式,或哪个数据库

B.使用哪种web服务

C.使用哪种框架

b.边界越完善,开发和部署成本越高。

所以不完全边界能解决的,不要用完全边界;低层次解耦能解决的,不要用高层次解耦

3.内容

a.组件拆分

i.切分

A.水平分层

B.按用例垂直切分

C.重复性

ii.解耦模式

A.源码层次

B.部署层次

C.服务层次

D.从上到下,开发、部署成本依次升高,如果低层次的解耦已经满足需要,不要进行高层次的解耦

b.组件排列(依赖)

i.依赖关系与数据流控制流脱钩,与组件所在层次挂钩。

所以组件的依赖是与组件的水平分层息息相关的

ii.分层

A.业务实体

B.用例

C.接口适配器

D.框架与驱动程序

E.测试层

c.组件通信

i.方式

A.接口调用

B.服务调用

ii.完全边界

A.调用双方都声明接口

B.专用的输入数据类型

C.专用的返回数据类型

iii.不完全边界

A.省掉最后一步:

保留到源码层次的解耦;声明好接口,做好分割后,仍然放在一个组件中,等到时机成熟时再拆出来独立编译部署

B.单向边界:

正常的切割,应该使用两个接口,两个类各自使用对方的接口,而不是直接使用类,但是这样的开发成本很大,所以,只实现一个接口,高层用接口调用低层,而低层直接使用高层的类

C.门户模式:

控制权的间接转移不用接口和实现去做,而是用门户类去做,接口都不用声明了

4.软件系统的生命周期

a.开发

i.不同团队负责的组件不交叉

ii.不使用大量复杂的脚手架

b.部署

i.减少组件数量,内部组件外部组件结合的方式

ii.不依赖成堆的脚本和配置文件

c.运行

i.这方面的价值对架构的影响最小

ii.不同吞吐量、不同的响应时长要求,是架构设计要考虑的点

iii.架构应起到揭示系统运行的作用:

用例、功能、行为设置应该都是对开发者可见的一级实体,以类、函数或模块的形式占据明显位置,命名能清晰地描述对应的功能

d.维护

i.探秘成本:

对现有软件系统的挖掘,确定新功能或修复问题的最佳位置和方式

ii.风险成本:

改动时,可能衍生出新的问题

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2