目录
1. 前言
2. 详细了解需求内容
3. 抽象软件架构
4. 详细软件架构
5. 举例说明
6. 参考书籍与概要
6.1. 一线架构师实践指南
6.2. 软件架构理论与实践
6.3. 架构整洁之道
1. 前言
对软件架构的定义有很多,我个人认为软件架构是基于需求产出高层面可理解的软件结构,可以指导开发过程并发且快速进行,对后续运维和扩展多具有指导价值。
关于软件架构的书籍有很多,有的介绍其采取的实施步骤,如一线架构师实践指南,有的仅是介绍名词概念,例如软件架构简洁之道,不过这些名词正式业界多年的经验总结。
我阅读一线架构师实践指南时,有一种英雄所见略同的感觉,因为个人在工作中践行的架构方式与该书所讲内容有部分交集。
接下来,讲述本人一直践行的一种方法论。
按照从抽象到具体的顺序,将整个过程简单分为三个步骤:
- 详细了解需求内容
- 抽象软件架构
- 详细软件架构
2. 详细了解需求内容
这个步骤中,需要参与需求评审,了解需求细节。
3. 抽象软件架构
首先需要抽象出业务模型,可以按照如下步骤进行:
- 列举需求内的参数者,包括人、物、有价值的名词。
- 对参与者进行分组,暂不考虑彼此关联性,而是按照类型粒度划分,同一类型内的参与者抽象为实体。
例子如下
从需求文档中列举出有价值的名词
- 理财师 用户 各种投资产品 订单 订单维度的佣金 当前月佣金 上一月佣金 组队 队长 成员 盟主 总监 团队佣金 当月销量 上月销量 达标队员
按照类型分类并抽象实体
- 用户类型: 系统用户实体(可标记为理财师 用户)
- 投资类型: 各种投资产品实体
- 订单类型: 订单
- 佣金类型: 订单维度佣金实体 当前月佣金实体(可标记为多种佣金类型) 月度佣金实体(可标记为多种佣金类型) 佣金系数规则实体
- 组队类型: 队伍实体 队长级别实体
- 统计类型: 当月投资销量(用户或团队) 上月投资销量(用户或团队) 当月团队达标情况实体 月度团队达标情况实体
截至到此,输入需求,已产出抽象模块,甚至作为子系统。这些就可以作为抽象的业务模型。
然后输出系统模型,依据数据的上下游依赖,绘制模块间关系,不要产生循环依赖。
4. 详细软件架构
无论系统分为多个模块或多个子系统,都可以通过分层 分区 机制分离的步骤去绘制逻辑架构。
无论是系统分为多个模块,还是多个子系统,需要考虑部署架构,包括但不限于考虑app、web、
应用实例、端口、容器、动态代理、路由规则、图片服务实例、cache实例、数据库实例等,至此
产出部署拓扑。
产出逻辑架构后,可以进行细节工作了,包括:
- 技术选型、框架选择
- 实体对应的数据模型设计
- 功能详细设计,设计模式、绘制流程图、时序图
- 工程内部包结构
至此,我们已经可以清晰可见模块或子系统间交互需要哪些接口,业务功能的详细流程,实体需要
存储哪些数据,可以为开发过程提供直观的依据。
6. 参考书籍与概要
6.1. 一线架构师实践指南
读后感:清晰描述每个步骤需要做的事情。
软件需求 = 功能需求 + 质量属性 + 约束
需求决定架构,且要考虑业务背景 系统规模 技术趋势 开发团队现状。
以场景明确非功能需求,目标 -> 场景 -> 决策。
不同的需求,以不同的方式影响架构:
- 功能是发现职责的依据
- 质量是完善架构设计的动力
- 约束 转化为上述种类
pre阶段:理解需求、建立需求大局观、确定架构设计方向。
明确的业务需求 -》 全面的用户需求 -》 典型的行为需求
分析业务需求以及约束后的隐藏需求
- 发现遗漏需求
- 确定关键需求
- 确定关键质量
- 权衡质量和属性之间的矛盾关系
使用如下矩阵明确需求范围:
业务 | 用户 | 开发 | |
功能 | |||
质量 | |||
约束 |
概念架构阶段
概念性架构 界定 系统的高层组件以及之间的关系。
细化架构阶段
逻辑架构,绘制步骤:
- 分层:职责划分
- 粒度:分区细化
- 机制:通用单元分离
数据架构、运行架构、物理架构、开发架构
6.2. 软件架构理论与实践
刻画软件系统整体抽象结构,软件架构由 组件 连接件 配置 端口 角色 五个元素构成。
组件 | 软件模块单元 可将单独jar作为一个组件 |
连接件 | 组件间交互 |
配置 | 组件与连接件的拓扑逻辑与约束 |
端口 | 组件通过接口与外部交互,组件接口由一组端口组成,每个端口是组件与外部的交汇点 |
角色 | 连接件的每个角色定义了连接件交互的参与者 |
6.3. 架构整洁之道
读后感:原则概念性描述,除此没有太多收获。
软件架构的最终目标,以最小的人力成本来构建和维护系统。
软件架构是重要的事情,业务功能是紧急的事情。
一些基本原则:
SRP 单一职责原则 | 一个软件模块只对一类行为者负责 软件模块理解为与行为者相关的类和数据模型 |
OCP 开闭原则 | 系统易于扩展,限制修改的影响范围。 将系统划分为多个组件,组件间按依赖关系构成层次结构,高阶组件不会因为低阶组件的修改而受到影响。 |
LSP 里氏替换原则 | 父类引用指向子类实例 |
ISP 接口隔离原则 | 使用Interface隔离行为者 任何层次的软件设计应只依赖需要的东西。 |
DIP 依赖反转原则 | 接口比实现更稳定 软件设计追求稳定,必须使用稳定的接口,而不是具体实现。 抽象工厂模式(工厂是抽象的,接口返回值是抽象的。由具体产品提供具体工厂和返回值实例) |
组件:软件模块单元,可将单独jar作为一个组件,例如三方包。列举构建组件的基本原则:
REP 复用 发布 等同原则 | 组件的复用粒度应与发布粒度相同 复用性 |
CCP 共同闭包原则 | 为相同目标而可能同时修改的类放到一起 维护性 |
CRP 共同复用原则 | 不是紧密相连的类不应该放在一个组件中 不要依赖带有不需要的类的组件 为避免不必要的发布而切分 |
组件耦合,管理组件之间的关系、隔离频繁的变更。
无循环依赖原则 | 组件间依赖关系应该为有向无环图 消除依赖环(依赖反转、新增组件) |
SDP 稳定依赖原则 | 依赖关系应指向更加稳定的方向 稳定程度 = 入向依赖/(出向依赖+入向依赖) |
SAP 稳定抽象原则 | 依赖关系应指向更加抽象的方向 |
软件架构
软件架构的最终目标: 最大化生产力,最小化运营成本(部署、运行、维护的成本)
所有软件系统都可以讲解为策略和细节。策略指的是系统的业务能力。细节指的是使用的技术栈、软硬件等。
高层策略 隔离 实现具体细节,推迟或延后与具体实现相关的细节可选项的决策,最大可选项的数量。
独立性(开发独立、部署独立)
划分边界(做什么不做什么)
策略与层次,距离输入输出越远,则层次越高。低层次的组件 依赖 高层次的组件。例如web模块负责处理输入输出,依赖高层模块,如服务模块、缓存模块。
业务逻辑,业务逻辑应为系统核心,其他底层概念应已插件形式接入系统。业务逻辑应是最独立、复用性最高的代码。
爬山的过程很累的...