目录

1. 前言

2. 详细了解需求内容

3. 抽象软件架构

4. 详细软件架构

5. 举例说明

6. 参考书籍与概要

6.1. 一线架构师实践指南

6.2. 软件架构理论与实践

6.3. 架构整洁之道


1. 前言

对软件架构的定义有很多,我个人认为软件架构是基于需求产出高层面可理解的软件结构,可以指导开发过程并发且快速进行,对后续运维和扩展多具有指导价值。

关于软件架构的书籍有很多,有的介绍其采取的实施步骤,如一线架构师实践指南,有的仅是介绍名词概念,例如软件架构简洁之道,不过这些名词正式业界多年的经验总结。

我阅读一线架构师实践指南时,有一种英雄所见略同的感觉,因为个人在工作中践行的架构方式与该书所讲内容有部分交集。

接下来,讲述本人一直践行的一种方法论。

按照从抽象到具体的顺序,将整个过程简单分为三个步骤:

  1. 详细了解需求内容
  2. 抽象软件架构
  3. 详细软件架构

2. 详细了解需求内容

这个步骤中,需要参与需求评审,了解需求细节。

3. 抽象软件架构

首先需要抽象出业务模型,可以按照如下步骤进行:

  • 列举需求内的参数者,包括人、物、有价值的名词。
  • 对参与者进行分组,暂不考虑彼此关联性,而是按照类型粒度划分,同一类型内的参与者抽象为实体。

例子如下

从需求文档中列举出有价值的名词

  • 理财师 用户 各种投资产品 订单 订单维度的佣金 当前月佣金 上一月佣金 组队 队长 成员 盟主 总监 团队佣金  当月销量 上月销量 达标队员

按照类型分类并抽象实体

  • 用户类型: 系统用户实体(可标记为理财师 用户)
  • 投资类型: 各种投资产品实体
  • 订单类型: 订单
  • 佣金类型: 订单维度佣金实体 当前月佣金实体(可标记为多种佣金类型) 月度佣金实体(可标记为多种佣金类型) 佣金系数规则实体
  • 组队类型: 队伍实体 队长级别实体 
  • 统计类型: 当月投资销量(用户或团队) 上月投资销量(用户或团队) 当月团队达标情况实体 月度团队达标情况实体

截至到此,输入需求,已产出抽象模块,甚至作为子系统。这些就可以作为抽象的业务模型。

然后输出系统模型,依据数据的上下游依赖,绘制模块间关系,不要产生循环依赖。

4. 详细软件架构

无论系统分为多个模块或多个子系统,都可以通过分层 分区 机制分离的步骤去绘制逻辑架构。

无论是系统分为多个模块,还是多个子系统,需要考虑部署架构,包括但不限于考虑app、web、

应用实例、端口、容器、动态代理、路由规则、图片服务实例、cache实例、数据库实例等,至此

产出部署拓扑。

产出逻辑架构后,可以进行细节工作了,包括:

  1. 技术选型、框架选择
  2. 实体对应的数据模型设计
  3. 功能详细设计,设计模式、绘制流程图、时序图
  4. 工程内部包结构

至此,我们已经可以清晰可见模块或子系统间交互需要哪些接口,业务功能的详细流程,实体需要

存储哪些数据,可以为开发过程提供直观的依据。

6. 参考书籍与概要

6.1. 一线架构师实践指南

读后感:清晰描述每个步骤需要做的事情。

软件需求 = 功能需求 + 质量属性 + 约束

需求决定架构,且要考虑业务背景 系统规模 技术趋势 开发团队现状。

以场景明确非功能需求,目标 -> 场景 -> 决策。

不同的需求,以不同的方式影响架构:

  • 功能是发现职责的依据
  • 质量是完善架构设计的动力
  • 约束 转化为上述种类

pre阶段:理解需求、建立需求大局观、确定架构设计方向。

明确的业务需求 -》 全面的用户需求 -》 典型的行为需求

分析业务需求以及约束后的隐藏需求

  • 发现遗漏需求
  • 确定关键需求
  • 确定关键质量
  • 权衡质量和属性之间的矛盾关系

 使用如下矩阵明确需求范围:

业务

用户

开发

功能

质量

约束

概念架构阶段

概念性架构 界定 系统的高层组件以及之间的关系。

细化架构阶段

逻辑架构,绘制步骤:

  • 分层:职责划分
  • 粒度:分区细化
  • 机制:通用单元分离

数据架构、运行架构、物理架构、开发架构

6.2. 软件架构理论与实践

刻画软件系统整体抽象结构,软件架构由 组件 连接件 配置 端口 角色 五个元素构成。

组件

软件模块单元 可将单独jar作为一个组件

连接件

组件间交互

配置

组件与连接件的拓扑逻辑与约束

端口

组件通过接口与外部交互,组件接口由一组端口组成,每个端口是组件与外部的交汇点

角色

连接件的每个角色定义了连接件交互的参与者

6.3. 架构整洁之道

读后感:原则概念性描述,除此没有太多收获。

软件架构的最终目标,以最小的人力成本来构建和维护系统。

软件架构是重要的事情,业务功能是紧急的事情。

一些基本原则:

SRP 单一职责原则

一个软件模块只对一类行为者负责

软件模块理解为与行为者相关的类和数据模型

OCP 开闭原则

系统易于扩展,限制修改的影响范围。

将系统划分为多个组件,组件间按依赖关系构成层次结构,高阶组件不会因为低阶组件的修改而受到影响。    

LSP 里氏替换原则

父类引用指向子类实例

ISP 接口隔离原则

使用Interface隔离行为者

任何层次的软件设计应只依赖需要的东西。

DIP 依赖反转原则

接口比实现更稳定

软件设计追求稳定,必须使用稳定的接口,而不是具体实现。

抽象工厂模式(工厂是抽象的,接口返回值是抽象的。由具体产品提供具体工厂和返回值实例)

组件:软件模块单元,可将单独jar作为一个组件,例如三方包。列举构建组件的基本原则:

REP 复用 发布 等同原则

组件的复用粒度应与发布粒度相同

复用性

CCP 共同闭包原则

为相同目标而可能同时修改的类放到一起

维护性

CRP 共同复用原则

不是紧密相连的类不应该放在一个组件中

不要依赖带有不需要的类的组件

为避免不必要的发布而切分

组件耦合,管理组件之间的关系、隔离频繁的变更。

无循环依赖原则

组件间依赖关系应该为有向无环图

消除依赖环(依赖反转、新增组件)

SDP 稳定依赖原则

依赖关系应指向更加稳定的方向

稳定程度 = 入向依赖/(出向依赖+入向依赖)

SAP 稳定抽象原则

依赖关系应指向更加抽象的方向

软件架构
        软件架构的最终目标: 最大化生产力,最小化运营成本(部署、运行、维护的成本)
        所有软件系统都可以讲解为策略和细节。策略指的是系统的业务能力。细节指的是使用的技术栈、软硬件等。
        高层策略 隔离 实现具体细节,推迟或延后与具体实现相关的细节可选项的决策,最大可选项的数量。

独立性(开发独立、部署独立)

划分边界(做什么不做什么)

策略与层次,距离输入输出越远,则层次越高。低层次的组件 依赖 高层次的组件。例如web模块负责处理输入输出,依赖高层模块,如服务模块、缓存模块。

业务逻辑,业务逻辑应为系统核心,其他底层概念应已插件形式接入系统。业务逻辑应是最独立、复用性最高的代码。

爬山的过程很累的...