第四季度,必须考过专业级
科目四:软件设计与重构 考纲
需求分析
- 理解软件需求分析基本概念和原则;
- 理解软件需求分析流程每个阶段关键活动及注意事项,如需求获取、分解、排序、验收、跟踪、变更等过程,以及需求相关文档等输出件的写作和验收要求;
- 理解需求分析需要关注的场景和维度,如功能需求、DFX需求(可维护性需求、系统资源与性能要求、安全需求等非功能性需求)识别;
- 理解需求分析和评估方法,如需求分解方法 、排序方法、安全威胁分析方法、系统资源占用分析、ASTRIDE分析方法等。
软件设计与建模
- 理解常见软件设计概念,了解常见的软件结构;
- 熟悉常用的软件设计方法和原则,如面向对象设计方法、SOLID原则等,了解领域驱动设计、演进式设计的实践;
- 熟练掌握软件建模方法和工具,如UML图、4+1视图等,能够使用工具表现合理的抽象封装;
- 了解23种经典设计模式的特点和应用场景,熟练掌握抽象工厂、适配器、工厂方法、观察者、策略 、状态、代理、外观、单件(singleton)、模板方法、装饰器模式的应用与实现。
可信设计
- 掌握常见软件设计中各个领域应用的安全威胁及对应的安全设计方法,包括身份和访问控制管理、密钥管理、会话管理、安全设计、隐私保护、密码学算法应用等;
- 掌握常见的安全设计原则及安全设计方法,包括安全开发设计指导规则(HCSEC Golden Rules)、安全设计原则、安全设计模式、威胁建模工程方法(ASTRIDE)等。
重构分析与实现
- 掌握重构的概念和原则,熟悉不同层级(函数级、模块级、架构级)软件重构的流程和方法;
- 掌握重构防护网的建设方法,能够识别重构的风险并建立相关质量保障措施;
- 掌握经典的坏味道识别方法;
- 掌握软件宏观和微观层面的代码重构手法,熟练掌握经典重构手法及其对应的反向重构方法的实施。
需求分析
需求分析基本概念和原则
需求分析的任务就是解决“做什么”的问题,就是要全面地理解用户的各项要求,并准确地表达所接受的用户需求。
需求分析的输入是目标,问题和场景,输出是形式化的功能规约,质量属性和设计约束,分析过程中要考虑众多涉众利益和DFX属性。
非功能需求等于质量需求,非功能需求主要指不明确的功能性需求,需求分析阶段应将不明确的功能性需求细化成功能性需求。
需求包括功能性需求、质量性能需求和约束。
需求分析活动和注意事项
总的来说,分为:
- 问题识别(确定业务目标、达成标准)
- 分析与综合(细化功能、非功能需求,排优先级)
- 规格说明(需求规格说明书)
- 评审(达成共同的理解和认识)
我司常用《基于用例(Use-Case)技术需求分析方法》,具体的活动是:
- 收集需求(访谈、考察、研讨等形式,识别功能、性能、质量、约束)优先级排序也在此
- 定义系统边界(明确系统的分析范围)
- 识别Actor(系统边界外、与系统有交互、人/物/定时器)谁使用系统、谁提供信息给系统、谁维护管理系统、自动触发的事件
- 识别Use Case(对Actor可见,对Actor有价值、系统实现)系统执行的一系列动作,生成Actor可观测、有价值的结果
- 整理场景(可在哪些用户场景使用,有哪些输入,适当组合归并)主场景、可选场景、异常场景
- 描述Use Case(详细、完整的用例阐述)用例图为骨架,用例规约为肉。名称、标识、简要说明、actor、前置条件、后置条件、正常/异常事件流、DFX、遗留问题
需求分析输出的质量准则包括完整性,正确性,可验证性和一致性。
补充需求获取的方法:
- 实地观察个人的工作情况
- 访谈,但要真实理解用户想解决的问题,不要被他的解决方案掩盖了实际的需求
- 特定群体调查(对一组人员调查,了解工作态度和共同看法)
- 问卷调查(统计意义上的数据)
- 用户指导(最终用户直接告诉,他们是如何操作系统的)
- 原型制作(涉及生命安全、高成本的)
- 统计版本(有统计功能的程序记录用户完成任务的方式)
补充需求优先级排序的方法:
- 入选与落选法: 二分法决定下一版本需求
- 三层分级:关注高优先级,如果还是超出工作量,再三分
- KANO模型法:基本型需求必须满足,期望型需求实现程度与客户满意度成正比
- 两两比较:小于20条需求可用
- 100美元法: 团队对需求标价,价高者优先级高
- 二八原则:优先满足收入占比80%的核心用户需求
- 性价比法:核心业务需求优先,投入产出比高的优先
需求管理
需求管理活动:
- 变更控制(保持项目计划与需求的同步、)
- 版本控制(项目团队和用户达成共识,定义需求基线)
- 状态跟踪(项目过程中,跟踪需求状态和变更情况)
- 需求跟踪(需求与设计、代码、测试用例联系起来)
可信设计
安全经典三要素:机密性(Confidentiality),完整性(Integrity),可用性(Availablity)
安全目标:完整性,保密性,可用性,隐私保护,可追溯性。
安全设计原则:
- 开放设计原则,安全不依赖保密,私有的“加密”算法。
- 失败-默认安全原则,失败安全,默认安全。
- 权限分离原则,分离不同进程的权责,三权分立(系统管理员,安全管理员,安全审计员)。
- 最小权限原则,确保应用程序使用最低权限运行,禁止使用最高权限连接数据库。
- 经济适用原则,简单,精巧,组件化,不要过度设计,更安全有效的组件化架构设计。
- 最小公共化原则,共享内存最小化,端口绑定最小化,减少连接,防御DoS攻击。
- 完全仲裁原则,每次访问都要校验用户权限,DNS缓存欺骗。
- 心理可承受原则,12306验证码,为用户着想的验证码,记住密码。
- 纵深防御原则,是一个综合性很高的防御原则,一般要求系统架构师综合运用其他的各类安全设计原则,采用多点、多重的安全校验机制,高屋建瓴地从系统架构层面来关注整个系统级的安全防御机制,而不能只依赖单一安全机制。
安全架构设计原则解读:
构建最小权限、纵深防御、最小公共化、权限分离、不轻信、开放设计、完全仲裁、失效安全、保护薄弱环节、安全机制经济性、用户接受度以及加强隐私保护的安全体系,确保系统、网络和数据的机密性、完整性、可用性、可追溯性。
ASTRIDE Low Level威胁分析
威胁建模流程:绘制数据流图,威胁分析,风险评估,制定消减措施,产品响应。
数据流图元素
外部交互方:能驱动系统业务,但不受系统控制的人和物(如用户,管理员,第三方系统等).通常表示目标系统的输入/输出。涉及到个人数据需要在元素概述中详细列举元素涉及的高、中、低影响的个人数据。
处理过程:一个过程执行一个任务时的逻辑表示,例如Web Server 、ftp server、LMT server
数据存储:数据存储表示文件、数据库、注册表项、内存等。涉及到个人数据需要在元素概述中详细列举元素涉及的高、中、低影响的个人数据。
数据流:数据在系统中的移动方向,如网络通讯、共享内存、函数调用等。涉及到个人数据需要在元素概述中详细列举元素涉及的高、中、低影响的个人数据。
信任边界:当数据流穿越不同的信任级别(区域)时,就存在信任边界,例如从用户态到内核态,从客户端到服务端等。
威胁分析
Spoofing仿冒,Tampering篡改,Repudiation抵赖,Imformation Disclosure信息泄漏,Denial of Service拒绝服务,Elevation of Privilege权限提升,Privacy:隐私(非法处理个人数据)。
外部交互方:能驱动系统业务,但不受系统控制的人和物(如用户,管理员,第三方系统等).通常表示目标系统的输入/输出。涉及到个人数据需要在元素概述中详细列举元素涉及的高、中、低影响的个人数据。
处理过程:一个过程执行一个任务时的逻辑表示,例如Web Server 、ftp server、LMT server
数据存储:数据存储表示文件、数据库、注册表项、内存等。涉及到个人数据需要在元素概述中详细列举元素涉及的高、中、低影响的个人数据。
数据流:数据在系统中的移动方向,如网络通讯、共享内存、函数调用等。涉及到个人数据需要在元素概述中详细列举元素涉及的高、中、低影响的个人数据。
信任边界:当数据流穿越不同的信任级别(区域)时,就存在信任边界,例如从用户态到内核态,从客户端到服务端等。
元素 | S(spoofing)仿冒 | T(tampering)篡改 | R(Repudiation)抵赖 | D(Info disclosure)信息泄露 | D(denial of service)拒绝服务 | E(Elevation of Privilege)提权 | P(privacy)隐私 |
---|---|---|---|---|---|---|---|
外部交互方 | √ | - | √ | - | - | - | √ |
处理过程 | √ | √ | √ | √ | √ | √ | - |
数据存储 | - | √ | √ | √ | √ | - | √ |
数据流 | - | √ | - | √ | - | - | - |
- 外部交互: 仿冒S, 抵赖R
- 处理过程: 全部
- 数据存储: 篡改T,抵赖R(审计日志),信息泄露I,拒绝服务D
- 数据流: 篡改T,信息泄露I,拒绝D
仿冒: 外部交互方(克隆手机)、处理过程(假的BTS基站)
篡改T: 处理过程(修改特性)、数据存储(改账单)、数据流(中间人攻击)
抵赖R: 外部交互方(管理员操作)、处理过程(日志逻辑)、数据存储(修改审计日志)
信息泄露: 处理过程(黑客秘钥)、数据存储(明文口令)、数据流(明文口令)
拒绝服务: 处理过程(程序崩溃)、数据存储(磁盘满)、数据流(网络断流)
提权: 处理过程(用户账户分配了其他权限)
隐私: 外部交互方(收集IMEI等)、数据存储(未匿名化)
仿冒S: 认证(密码、SSL、IPSec、SSH)
篡改T: 完整性(Hash、MAC、数字签名、ACL)
抵赖R: 防抵赖(认证、审计日志)
信息泄露I: 机密性(加密、ACL)
拒绝服务: 可用性(负载均衡、过滤、缓存)
提权: 授权(权限最小化、沙箱)
隐私: 合法(匿名化、用户可知可控、数据最小化)
隐私威胁分析:可识别,不一致,不可控,不可知,不安全。
增量分析场景:绘制数据流图,变更识别,危险分析,风险评估,制定消减措施,产品响应。
场景化扩展:场景化构建,绘制数据流图,变更识别,危险分析,风险评估,制定消减措施,产品响应。
加密算法
安全: AES>=128, SHA256, ECDSA>=256, ECDH>=256, RSA>=2048, DSC>=2048, DH>=2048
遗留系统可用: 3DES(k1/k2/k3各不相同), RC4>=128, SHA1, RSA_1024, DSA_1024, DH_1024
不安全: Blowfish, DES, DESX, RC2, Skipjack, 2TDEA, TEA, SEAL, CYLINK_MEK, RC4<128, SHA0, MD2/4/5, RIPEMD*, RSA<1024, DH<1024, ECDSA<=160
密码哈希: PBKDF2, BCRYPT, SCRYPT, Argon2
PBKDF2是标准的密钥派生函数
软件设计与建模
软件建模体现了软件设计的思想,在需求和实现之间架起了一座桥梁,通过模型指导软件系统的具体实现。模型并不是软件系统的一个完备表示,而是所研究的系统的一种抽象。软件建模通过不同的视角去描述一个系统。
软件建模体现了软件设计的思想,在需求和实现之间架起了一座桥梁,通过模型指导软件系统的具体实现。模型并不是软件系统的一个完备表示,而是所研究的系统的一种抽象。软件建模通过不同的视角去描述一个系统。
UML内容组成:
事物:结构事物(用例、接口、协作等),行为事物(交互、状态机),组织事物(包),辅助事物(注释)。
关系:关联,依赖,泛化,实现。
图:静态图(用例图,类图,对象图,组件图,部署图),动态图(顺序图,合作图,状态图,活动图)。
软件系统架构的定义:系统架构 = 组件 + 交互 + 重要决策集。
安全架构的定义: 安全架构 = 系统业务架构 + 安全控制集。
提供架构4+1视图集:
- 逻辑视图:系统架构师, PM, SE。
- 运行视图:SE, 开发, 测试工程师。
- 数据视图:数据库, 开发工程师。
- 物理数图:运维, 部署工程师。
- 开发视图:开发, 配置工程师。
UML 4+1视图:
- 逻辑视图:类图,对象图。
- 实现视图:组件图。
- 部署视图:部署图。
- 行为视图:顺序图,合作图,状态图,活动图。
- 用户视图:用例图。
UML在软件开发流程中的应用:
- 需求分析:用例图。
- 概要设计,详细设计:类图,对象图,合作图,顺序图,状态图,活动图。
- 编码阶段:无
- 测试:类图,组件图,部署图。
视角和类图:
- 交互化视角:用例图。
- 结构化视角:类图。
- 行为视角:顺序图,活动图,状态图。
用例图包含关系:
Include:包含也可以叫Use,表示本用例会用到被包含的其他用例,被包含的用例是可以被重用的。
Extend:扩展用例是可选的,在特定场景下可以补充基础用例,降低基础用例的复杂性。
Generalization:泛化体现了父子关系,表明存在派生和继承。
类图包含关系:
实现(Realization):是一种类与接口的关系,表示类是接口所有特征和行为的实现。例如:借阅者能查找书籍。
依赖(Dependency):是一种使用的关系,有单向依赖和双向依赖,但避免使用双向依赖。例如:借阅者查找结果依赖标题。
泛化(Generalization):是一种继承关系,指定了子类继承父类的所有特征和行为。例如:借阅者是老师或者学生。
关联(Association):是一种拥有的关系,它使一个类知道另一个类的属性和方法。例如:借阅者的借阅记录或预约记录。
聚合(Aggregation):是整体与个体的关系,可以理解成把个体聚集在一起。例如:借阅者的多条借阅记录。
组合(Composition):是整体与局部的关系,整体的对象负责代表局部的对象的生命周期,可以理解成整体是由局部组成的。例如:借阅记录必须要有相关书籍信息。
各种关系的强弱顺序: 泛化=实现>组合>聚合>关联>依赖
三角实线=三角虚线>菱形实线>菱形虚线>箭头实线>箭头虚线
记忆技巧: 类图关系连线的箭头,指向内容和范围较小的类。
箭头指向接口、父类、依赖的内容;菱形指向整体
用例图描述系统在干什么。动态模型是描述系统的功能是如何完成的,用顺序图、活动图和状态图从不同的角度来描述对象和对象之间的交互。
动态图作用和场景:
顺序图:强调消息时间顺序的交互图。描述复杂的多对象间交互。并发、分支过多的场景会影响可理解性。
活动图:用于对目标对象计算流程和工作流程建模。描述涉及到复杂的活动步骤的用例。特别并发、分支等场景。
状态图:描述了系统元素的状态条件和响应,它反映了类的对象可能具有的状态,以及引起状态变化的事件。涉及到复杂的状态变化的场景,也适用于并发场景,如网络连接的会话状态等。状态图仅用于具有下列特点的类:具有若干个确定的状态,类的行为在这些状态下会受到影响变为其他状态。
题目:
用例图中的Include关系是对应的UML四个关系中哪一种关系: 依赖
设计模式
正交四原则:
- 最小化重复
- 分离变化
- 缩小依赖范围
- 向稳定方向依赖
SOLID原则:
- 单一职责SRP,一个类,引起它变化的原因只有一个。如果一个变化,导致多处修改,则存在重复。
- 开闭原则OCP,对扩展开放,对修改关闭。多个变化导致一处修改,则对变化的识别不准,容易考虑不周,修改引入。
- 里氏替换原则LSP,基类设定一系列的规范和契约,子类需要遵守。
- 接口分离原则ISP,客户只需要了解必须了解的。不要暴漏的细节。
- 依赖倒置原则DIP,接口为稳定的契约,双方都依赖于抽象,不依赖于具体实现;上层定义接口,下层实现接口
23种设计模式:
创建型:
- Factory Method(工厂方法):隔离创建对象的细节,使得创建对象的行为可扩展
- Abstract Factory(抽象工厂):该模式抽象出创建一组相关对象的接口,其中每个方法即为factory method
- Builder(建造者):与factory不同的是,该模式包含了对象构造的若干过程,因此天然地与template结合
- Prototype(原型): 用于以某个对象为模子创建一个新对象的场景,例如幻灯片中的母版与普通页、对象的克隆
- Singleton(单例):
结构型:
- Adapter Class/Object(适配器):处理遗留系统的不二法宝,也可以用空方法实现接口作为抽象父类
- Bridge(桥接): 使用关联代替继承,解决类多维度的扩展导致的类爆炸的问题
- Composite(组合):将组件组装为整体使用
- Decorator(装饰):常见于各种wrapper,常用于在原函数执行前后做一些额外的工作
- Facade(外观):封装扇出,利用树状结构减少调用者的复杂度
- Flyweight(享元):复用变化少的对象
- Proxy(代理):是原对象的一个完整的替代品
行为型:
- Interpreter(解释器):一般用于解释执行自定义的某种语法
- Template Method(模板方法):框架与钩子
- Chain of Responsibility(责任链):一组对象按照既定的顺序关联起来,依次处理请求,其中任一对象都有权停止调用传递
- Command(命令): 将行为抽象和解耦
- Iterator(迭代器):封装数据的访问行为(顺序、可见性等)
- Mediator(中介者):用一个中介对象来封装一系列的交互;新增一个模块处理两个模块的交互
- Memento(备忘录):将当前对象的状态信息保存为另一个对象,使得当前对象可以基于状态镜像快速恢复原状态
- Observer(观察者): 订阅/发布模型,用于事件驱动的设计
- State(状态):封装FSM(有限状态机)的状态与状态迁移,每个状态定义了自身的输入与状态迁移
- Strategy(策略):使用接口即使用strategy,用于隔离变化
- Visitor(访问者):数据与行为分离方法。通过这种分离,可达到一个被访问者动态添加新的操作而无需做其他的修改的效果