软件设计是什么?
一种创造性的活动,力求以简单优雅的方式解决实际问题、
软件设计是一门技术:数据结构,组成原理,操作系统,编程语言。
软件设计是一门艺术。
并不是技术知识的简单堆砌,分析抽象,取舍。
软件设计的意义(构架的意义)
软件设计:功能,部署,交互,复用性,维护性,扩展性。
特定:
是一个塑造模型(概念)的过程
是一个取舍的过程,
是一个分而治之的过程
是一个在理性范围内追求完美的过程
什么是软件质量?
用户角度:defect和bug的数量越少意味着质量越好。
开发角度:
整体架构设计易于扩展,模块之间耦合性低,易于复用。代码简洁易懂,易于维护。
如何提高软件质量?
编码前,架构设计质量必须得到保证。
编码时,代码质量必须得到保证。
编码后,测试质量必须得到保证。大的学科,质量影响最后质量
架构设计 vs 软件质量
设计:
模块1《---》接口1《---》模块2《---》接口2《---》模块3
开发流程 vs 软件质量
需求分析->架构设计->架构审核->审核通过?->模块实现->代码审核->审核通过?->测试
软件测试 vs 软件质量
需求分析->测试用例设计->测试用例审核->审核通过->测试用例执行->用例通过(评定bug级别,记录bug重现步骤,记录测试环境信息)->测试结束->反馈测试结果
为测试正名:
在需求分析结束后,测试人员就需要介入项目。
根据需求分析进行功能测试用例的设计。
根据架构设计进行模块测试用例的设计。
根据产品标准进行压力测试用例的设计。
开发中的常见问题:错误的
测试是替罪羊或救命稻草:但凡出现bug,就是测试不给力。
资源永远不足:现在没有时间和精力去做重构。
不改变就可以规避风险:虽然有缺陷,但是功能不受影响,不做改变。
如何提高自身的软件设计能力?
对架构的完美性有精神上的追求,不满足功能正确:积极思考方案,不停反思是否能做的更好。
勇于实践与模仿,进而形成自己的风格和思想:推敲前辈们的经典设计,尝试用于自己的项目。
总结设计原则,体会各个设计原则的内涵:软件设计不是原则的叠加,而是一个平衡利弊的过程。
设计思想,设计原则,设计模式
设计思想:设计原则1设计原则2设计原则3设计模式123
小结:软件设计(架构)的质量决定了软件质量的基调。
测试质量和代码质量直接决定了最终产品的质量
正规开发流程中测试人员先于编码人员介入项目。
软甲架构设计能力需要通过实践提高,需要总结和体会。
19、设计,软件质量之本中
设计原则-1:以人为本
核心:将现实世界直接映射到软件设计。
意图:便于沟通和理解,降低复杂性,增加维护性。
要点:使用现实世界中的概念。
案例:任务与内存访问:
TaskA(memory1 A) TaskB(Memory2 AB )TaskC(B)
将权限引入。
架构图:
task--ABC---check privilege
设计原则2:简单就是美
核心:用最简单的方法描述解决方案
意图:便于沟通和理解,降低复杂性,增加维护性。
要点:使用团队熟悉的技术进行设计。
案例:删除格式化字符串中的指定子串
例:abc{xxx}de->abcde
方案一:用正则表达式
sscanf(s,"%[^{]",real);
sscanf(s,"%*[^}]%s",ru);
sprintf(s,"%s%s",realm,ru+1); 正则表达式求出来的包括右括号
方案2:
方案3:
int b=tmp.indexof("{");
int e=tem.indexof("}");
tmp.remove(b,e-b+1);
sprintf(s,"%s",tmp.str());
简单些 vs 灵活性
简单性不等于灵活性
简单的设计易于催生灵活的设计。
过于追求灵活的设计可能导致复杂性的增加。
设计原则3:让模块善始善终
核心:模块的初始化与模块的终止同等重要
意图:确保模块状态的恢复和保存
要点:对称式设计
案例:模块的动态加载(初始化)与卸载(终止)
module* m=load_module("t,t,");
设计方案:强行设计析构函数
设计原则4:重视运行时数据的收集
核心:考虑程序运行状态数据的收集模块
意图:监控程序运行状态,便于调试与测试。
案例:统一日志模块的设计
ABC模块-->log Module(日志的输出存储)--->内存,网络,串口,文件
案例:程序状态统计模块的设计
小结:
构架设计时尽量将现实中的概念映射到程序中。
开发过程中的任意阶段都提倡见到优美的设计方式。
模块设计时需要同时考虑初始化过程与终止过程。
架构设计时需要考虑保证产品质量的辅助手段。
20、设计软件质量之本下
设计原则5:代码自注释
核心:代码自身就能够很好的进行功能性说明
意图:便于沟通和理解,增加维护性
代码质量:
最终的产品代码应该“非常容易”读懂
注释作为补偿说明必不可少,但不是越多越好
注释应该起到画龙点睛的作用,用于简要的描述代码意图,避免使用注释描述程序的运行流程。
设计原则6:通过机制解决当前问题
核心:考虑当前设计是否存在“漏洞”
意图:杜绝类似问题的再次发生。
案例:消息传递
三次握手:
A->B(req)
A<-B(rsp)
A->B(ack)
问题:当A设备无法收到B设备的RSP消息,会发生什么?
A设备等到rsp,B设备等待ack
解决方案一:让b设备定时重发rsp消息。
解决方案二:增加消息中转层,功能定义:负责所有设备间通信消息的发送和接收,处理所有通信异常的处理(阻塞重发,报告错误,etc)
异常后,中转层重复,发不出去告诉AB。
架构经验:设计不是一次性完成的,需要根据实际问题进行重构。
设计原则7:防御性程序设计
核心:防止他人意外错误
意图:提高代码鲁棒性。
案例:定时器模块的设计与实现
创建定时器后每隔指定的时间能够触发时间。
时间的具体表现为关联的回调函数被调用。
程序。
小结:尽量使用代码自注释的方式编写代码,便于沟通维护。
注意作为补充说明必不可少,但不是越多越好。
思考bug是否因为设计不当造成,通过机制解决问题。
通过防御性程序设计提高代码鲁棒性。