软工概念
面向对象特征
- 封装 Encapsulation 封装:限制对某些信息的访问
- 交互 Interaction 交互:通过过程调用或类似的协议
- 多态 Polymorphism 多态:在运行时选择具体的操作
- 继承 Inheritance 继承:对共享的功能保持唯一的接口
面向对象的缺点
- 操作太多对象
- 操作太多交互
- 与表现有关的职责被严重分开,使系统难以理解
- 难以捕捉相关设计所属的族(仅仅类型经常不足以,需要设计模式介入)
- 纯 oo 设计导致系统巨大且扁平
- 需要额外的 structure 和 discipline
解决方法
利用额外的结构和准则
C/S
- 进程即对象
- Asymmetric 客户端知道服务器,服务器不知道客户端
优点
- 高效利用网络系统,硬件成本可能变低
- 易于新增和更新现存服务器
- 允许多个用户共享数据
- 可扩展:增加新客户
缺点
- 每个 sever 拥有大量管理
- 难以找到什么服务器和服务是可用的,缺少一个中心来注册服务和服务器
- 难以改变服务器和客户的功能,改变 cs 架构的应用逻辑很困难
- 应用扩展被服务器和网络容量限制
两层 cs:重客户,轻服务 用户系统界面层 数据库管理服务层
限制
- 对客户端软件和硬件要求高
- 复杂的客户端程序设计
- 数据安全性差,客户端能直接访问服务端数据
- 相同的信息内容和格式
- UI 不同而且复杂
- 系统维护和升级复杂,所有客户端都需要维护
三层 cs 客户层的逻辑拆分到逻辑层,只保留表达层
BS 是三层 cs 的特例 但是限制了服务端资源和客户端资源的应用 安全性难以保证 在数据请求和速度上 BS 慢于 cs
分层
- CS 模式的扩展(Elaboration)
- 运行时层的结合 Aggregation into run-time strata
- 通常只有少量层
优点
- 每一层包含相关服务,内聚高
- 每一层对其他层隐藏了信息
- 每一层可能只会用到比它低的层,内聚高
- 易于复用,替换和交换
缺点
- 可能造成性能问题
- 清晰的层关系难以构建
框架
- 框架是对具体问题的可复用基础设施
- 包括为具体问题准备的必要基础组件
- 交互策略和组件依赖相结合
- 被开发应用的上下文和环境基于提供的框架
通常情况下,框架代表一个类库
非功能性需求
即质量属性(Quality Attributes)
常见的有
- Availability 可利用性
- Modifiability 可修改性
- Performance 性能
- Security 安全
- Testability 可测试性
- Usability 可用性
表述质量需求时,要定量而不是定性
使用这样的模版
- 刺激源(Source of Stimulus/Source):谁触发了刺激
- 刺激(Stimulus): 影响系统的 situation
- 制品(Artifact):被影响的那部分系统
- 环境(Environment):当刺激发生时,系统的状态
- 响应(Response):刺激的结果
- 响应衡量指标(Response Measure):如何衡量回应
可访问性 Availability
当用户使用系统时,系统可用的概率(系统故障所致)
(提前确定的停机维护不计入)
常见指标
- 可用(不可用)时 间占百分比
- 修复错误需要的时间
- 平均错误间隔时间
刺激源:失败的 signs 刺激:
- 系统错误
- 系统崩溃(重复的错误,无法回避)
- 不准时的结果(过早或过晚)
- 返回错误的结果
总结
可利用性的关注核心:
- 是否错误发生
- 故障的后果
提示可利用性的策略
-
错误检测
- ping
- 心跳包
- throw catch handle
-
错误修复
- 内部测试(阿尔法测,确认修复后再发补丁)
- 在检查点回滚,频繁保存
- 双系统保持同步,只取其中一结果
- 使用单系统,但是将变更通知另一系统,
- 如果其中一个挂了,确认另一个状态是最新的,使用另一个,
- 切换回来后需要重新同步主系统
- Vote,各种算法都能计算同一个问题,结果少数服从多数
-
错误避免
- ex.进程监控,最典型的是系统任务管理器
- ex.多个行为,整合成事务 transaction,一旦其中一个失败,另一个需要被取消
- ex.服务下线
性能 performance
关注点:
- 系统对事件响应的速度
- 事件的数量与到来模式
到来模式
- 随机
- 在特定时间尺度上有规律
指标
- 计算事件所用时间
- 单位时间计算的事件数
- 计算失败率和丢失率
提升策略
在任务对资源需求层面上控制
-
数据量不变时提升计算效率
-
减少数据总量
- 控制事件到来速率
- 仅计算请求的子集
-
限制执行时间
- 特定时间内只获取差不多的解
-
限制事件队列长度
- 直接遗弃一部分事件
在资源本身管理层面上控制
- 优化同步策略
- 多线程
- 多计算
- 多核多机
- 提升可用资源
- 可计算资源
- 存储资源
- 带宽资源
在资源仲裁层面控制
- 先来先服务
- 固定的优先级调度
- 动态优先级
- 无饥饿
- ddl 最早先进行
可修改性 modifiability
关注点
- 修改的成本
- 系统哪一部分被修改
- 修改什么时候发生
- 谁执行修改
计量指标
- 完成修改所需时间
- 修改的人力成本
- 修改的经济成本
- 等 等
提升可修改性的策略
- 限制修改范围,控制被修改影响的范围尽可能小
- 保持高内聚低耦合,引入框架和中间件,控制在单一模块
- 思考潜在修改,评估模块之间的指责分配,确保一点修改只会影响一个模块,避免不相关的多个修改影响相同模块
- 模块公共化
- 隐藏信息,面向对象的 public/private
- 维护连续接口(保证独立的改变能发生在接口两端,而不改变接口本身)
- 限制沟通路径(使用 facade 设计模式)
- 使用 intermediaries,共享数据,桥模式和工厂模式等
- 命名服务,实现 location 依赖
- 创建定制实例,使用创建相关的设计模式
- 延迟绑定时间,允许程序能在运行时被灵活修改
- 配置文件(修改配置文件而不是修改代码)
- 发布订阅模式
- polymorphism 使用不同子类实现不同功能
可用性 usability
关注点
- 减少用户使用软件等困难程度
环境
- 运行时
指标
- 一秒内取消操作的次数
策略
目标:使用户轻松
方向 1: 运行时策略
- 系统预测用户任务(如输 入预测,搜索建议)
- 系统提供合适的 feedback(如加载条,任务剩余时间)
- 系统为用户提供连续的体验(如调整某设置能在不同场景下提供解决方案)
方向 2: 设计时策略
- 支持撤回 undo 操作(最小化意外操作的影响)
- 隔离 ui 和系统其他部分(利用 mvc 模式,允许用户自定义 ui)
安全性 Security
关注点: 在合法用户能使用系统时,制止对系统的攻击
指标
- launching 攻击的困难度
- 从攻击中恢复的困难度
解决方案
制止攻击
- authentication 用户认证(密码)
- authorization 用户鉴权
- 维持数据可信 confidentiality (加密程序和数据)
- 维持数据完整性 Integrity(MD5 码校验)
- 减少暴露 exposure (禁止非必要端口,自启动服务)
- 访问控制(白名单,黑名单)
检测攻击
- 人与软件结合 侵入式检测系统,安全专家
- 恢复状态
- 对攻击者的辨认
从攻击中恢复
安全实例
- 基于当前时间戳的动态密码