1 理解软件设计
1.1 软件设计的定义
- IEEE 1990:设计是架构、构件、接口、以及系统其它特征定义的过程
- 软件设计(的结果)必须
- 描述系统的架构(architecture)
- 系统如何分解(decompose)和组织(organize)构件
- 结构化方法中称为概要设计、结构设计
- 描述构件间的接口(interface)
- 描述构件(component):必须详细到可进一步构造的程度
结构化方法中称为模块设计
- 描述系统的架构(architecture)
1.2 软件设计的任务
按照软件设计的定义,软件设计应包括以下方面的工作
- 架构设计(Architecture Design):确定软件如何分解成各部分(即构件或模块)及各部分之间的相互关系(即接口)
结构化方法中也称:总体设计、高层设计 - 构件设计(Component design):确定构件内部的结构,产生描述各构件详细文档
- 面向对象的方法对应于类设计,描述构件内各设计类的详细信息
- 结构化方法中称构件为模块,模块设计可过程(算法)设计、数据设计等内容
1.3 软件设计方法
- 结构化设计方法
- 基于过程的分解
- 架构设计:按照过程将系统分解成不同的模块,模块最小粒度为函数级别
- 构件设计:关注各个模块的内部算法、数据结构、用户界面等设计细节
- 面向对象的设计方法
- 基于对象的分解
- 架构设计:关于对象层次结构的组织,通过分层和分区,将软件分解成不同层次的构件,构件的最小粒度为类
- 构件设计:关注各种类(包括界面类、控制类、实体类、接口类等)的内部设计细节
1.4 软件设计的作用
- 软件设计在软件系统开发过程中扮演重要角色
- 开发者作出各种模型,形成实现时解决方案的蓝图
- 对这些模型进行分析和评价,以判定是否满足各种需求
- 便于考察备选方案和可行的替换措施
- 设计模型也可用于规划后续的开发活动
- 是编码和测试的输入
2 理解架构设计
2.1 软件架构的定义
- 软件架构是定义系统解决方案(Structured Solution)的过程,用于满足所有的技术和业务需求,同时优化系统的质量属性(如:性能、安全性、可管理性等)
- 架构设计活动包括一系列的设计决策,综合考虑各方面的影响因素,每个决策都会影响系统的质量、性能、可维护性,以至于最终使得系统获得成功
- 软件系统架构由系统的一组结构组织,其包含了各类软件元素、外部可见属性和它们间的关系
2.2 架构的重要性
软件架构的重要性在于它决定了一个系统的主体结构、宏观特性和具有的基本功能以及属性
- 架构是系统的骨架,复杂软件设计的成功在于系统有宏观层次上结构设计的正确性和合理性
- 是软件成功的基础,不仅支持所需的功能,同时能够促进或拟制非功能质量属性
3 架构设计模式
- 架构不是从零开设设计的,类似系统的参考架构具有很大的借鉴意义
- 架构模式是那些由软件架构师通过持续实践,进而总结出的、过往已验证的、优秀设计架构
- 架构模式是在给定上下文的软件架构中,针对常发生问题的一种通用、复用的解决方案
它帮助定义了软件系统的基本特征和行为
典型的软件架构模式
- 分层( Layered Architecture )
- 事件驱动(Event-Driven Architecture )
- 微内核(Microkernel Architecture )
- 微服务(Microservices Architecture Pattern)
- 虚拟化/云化(Space/Cloud-Based Architecture)
3.1 分层架构
-
分层架构(即N-Tier)最常用的架构模式
- 大部分企业级应用的标准模式
- 分层架构模式符合传统的IT公司沟通和组织结构,使得它成为大多数业务系统最自然的选择
-
在分层架构模式中
- 将应用分成多个水平层,每个水平层在应用中担任一个专门角色
- 大部分这种模型都由4个标准层次构成
表现层、业务层、持久层、数据库
-
分层架构的优势和适用性
- 分层架构的主要特点在于各个组件各司其职,相互分离
- 优势:
- 组件只属于某个特定层面,具有良好的易测试性(接口一致)
- 大多数业务能够划分为逐层分离的功能集,易于被开发
- 不同层次相对独立,便于分配单独的开发“角色”(在不同的层次分离技术和业务关注点)
- 便于对不同层次进行单独地更新与增强
-
分层架构的适用性
- 标准化业务线应用程序,且在功能上不限于CRUD(增删改查)操作
- 需要快速构建的新应用
- 团队中有并不了解其他架构、或经验不足的开发人员
- 需要具有严格的可维护性和可测试性的应用
3.2 事件驱动
-
事件驱动架构是一个非常流行的异步分布模式,可生成高可扩展性应用
具有强适应能力,可被用于小程序或者大型复杂程序 -
事件驱动架构是由高耦合度、单一目的的事件处理模块构成
这些模块异步接收、处理事件 -
事件驱动架构模式有两种主要拓扑结构,其结构的特征和执行策略不同
- 中介人(Mediator):通常用在一个事件中由多个步骤组成,需要通过集中“中介人”模块去调度这些步骤
- 代理(Broker): 当需要执行一系列事件链,而不需要集中“中介人”
- 中介人(Mediator):通常用在一个事件中由多个步骤组成,需要通过集中“中介人”模块去调度这些步骤
-
事件驱动架构的优势和适用性
- 主要用于开发具有高度可扩展性系统的分布式异步架构
- 优势:
- 容易适应复杂且混乱的环境
- 可被轻松地扩展
- 当出现新的事件类型时,能够方便地进行扩展
- 适合性:
- 具有异步数据流的异步系统
- 各种外部通知接口
3.3 微内核
-
微内核架构(插件架构)是实现基于产品应用程序的一种自然模式
- 基于产品的应用程序是已经打包好并且拥有不同版本,可作为第三方插件下载的
- 可让用户添加额外的应用如插件,到核心应用,继而提供了可扩展性和功能分离的用法
-
微内核系统架构模式由两块组成:内核系统和插件系统
应用逻辑分为独立的插件模块和基本核心模块,继而有扩展性、灵活性同时隔离应用程序功能和处理特定事物逻辑
-
微内核架构的优势
- 微内核模式能够从扩展功能、以及特定于客户的部件中,分离出最小的功能核心,再通过插件扩展其他功能
- 优势:
- 具有极大的灵活性和可扩展性
- 具有良好的可移植性,能够快速地响应不断变化的环境
- 插件模块既可以单独地被测试,又可以由核心系统来轻松地进行模拟,以演示或原型化某项特定的功能,进而达到对核心系统的尽少、甚至不做修改
- 适用性
基于产品的可扩展性开发模式
3.4 微服务
-
微服务架构模式正在迅速成为行业中单体应用程序及面向服务架构的可行的解决方案
- 该架构模式仍在不断发展
- 将业务分解为多个协同工作的微服务,每个微服务都有自己的“职责”,团队可以独立于其他微服务进行开发
-
微服务架构的优势和适用性
- 微服务架构中各个服务相对独立,通过统一接口协议进行通信
- 优势:
- 可以单独地编写,维护和部署每一个微服务
- 可以灵活地仅扩展那些需要的微服务
- 通过提供良好的可维护性和可测试性,以实现快速且频繁的开发和部署
- 适用性
- 有明确边界的企业级数据中心
- 快速发展的新业务和Web应用
- 具有遍布全球的开发团队
3.5 虚拟化/云化
- 虚拟化/云架构适用于解决高可扩展性和高并发问题
- 适用于用户规模具有很大的变化或不可预见性的系统
- 通过虚拟化技术比传统的分布式架构具有更好的可扩展性和灵活性
4 架构设计过程
4.1 确定架构原型
- 常用的应用程序类型
- 移动端应用
- 富客户端应用
- 富Web应用
- 传统的Web应用
- 面向服务的应用
4.2 选择部署策略
- 定义部署策略
- 应用程序必须部署到物理环境,受限于物理环境的约束,考虑应用程序架构
- 在架构设计时,需要结合物理环境定义部署策略
- 调研目标物理环境
- 综合考虑架构和设计约束,规划目标部署策略
- 安全性、通信策略等影响物理部署
- 两种部署策略:集中式部署和分布式部署
- 集中式部署
除了后台数据库,系统其他所有的功能和层次均部署在一个节点上- 简单、成本低
- 应用间不需要通信,单应用效率高
- 分布式部署
- 根据功能或逻辑分层将系统部署在不同的节点上,相比于集中,需要进一步考虑
- 通信
- 事务和安全(认证/授权)
- 状态管理
- 常见的分布式部署模式
- 客户-服务器结构
- 多层结构
- 根据功能或逻辑分层将系统部署在不同的节点上,相比于集中,需要进一步考虑
4.3 确定技术方案
根据架构和部署策略选择技术路线
- 应用框架/分层技术(Spring Cloud、.Net Core、Django…)
- 开发工具(IDEA、NetBeans、Eclipse、VS、PyCharm…)
- 数据库服务器(MySql、Oracle、Sql Server、Neo4J…)
- 数据库访问(Hibernate、MyBatis…)
- 工作流(JBPM、Activiti、WF …)
- 消息/通信(Kafka、…MQ、WCF…)
- 富客户端技术、移动端技术、富Web技术、服务技术、Web技术
- Web服务器(Apache、Nginx、IIS…)
4.4 解决质量属性
-
定义质量属性
质量属性是系统的全局特征,涉及到系统的不同层次,可以分为以下质量属性- 运行时
- 设计时
- 用户体验
-
性能问题
- 系统性能问题是大部分系统都需要面对的问题
- 针对性能问题有两类解决方案
- 纵向扩展系统(提高单台服务器的性能)
- 横向扩展系统(采用分布式部署,增加多个应用)
-
负载均衡策略:利用多台服务器解决性能问题
-
可靠性问题
- 可靠性是确保系统提供可靠的服务,避免系统失效
- 采用冗余策略解决可靠性问题
-
安全问题
- 认证(Authentication)
- 授权(Authorization)
- 输入/数据校验(Input and Data Validation)
- 敏感数据保护(Sensitive data)
- 配置管理(Configuration Management)
- 加密(Cryptography)
- Session管理(Session Management)
- 审计和日志(Auditing and Logging)
- 异常处理(Exception Management)
-
缓存问题
- 缓存在系统性能中扮演重要的角色,缓存设计时主要考虑的问题
- 哪些数据需要缓存
- 缓存的位置
- 缓存数据的格式
- 合适的缓存管理策略
- 如何加载缓存数据
- 两种缓存方案
- 独立的缓存服务器(Redis)
- 各级集成的缓存(页面缓存、数据缓存…)
- 缓存在系统性能中扮演重要的角色,缓存设计时主要考虑的问题
-
通信/消息/状态管理等问题
在多层应用中,还需要考虑各类其他问题- 通信问题:协议、接口
- 消息:同步、异步
- 状态管理














