参考:
代码大全2 | ProcessOn免费在线作图,在线流程图,在线思维导图
一些个人体会
- 软件工程的本质是管理复杂度
- 设计接口的时候想一下别人是否只看了接口就知道是怎么用的,而不需要关注接口内部细节
一些觉得有道理的核对表
核对表:软件构造中的设计
设计实践
1、你已经做过多次迭代,并且从众多尝试结果中选择最佳的一种,而不是简单选择第一次尝试的结果吗?
2、你尝试用多种方案来分解系统,以确定最佳方案吗?
3、你同时用自下而上和自上而下的方法来解决设计问题吗?
4、为了解决某些特定的问题,你对系统中的风险部分或者不熟悉的部分创建过原型、写出数量最少的可抛弃的代码吗?
5、你的设计方案被其他人检查了吗(无论正式与否)?
6、你一直在展开设计,直到实施细节跃然纸上了吗?
7、你用某种适当的技术——比如说Wiki、电子邮件、挂图、数据照片、UML、CRC卡或者在代码写注释——来保留设计成果吗?
设计目标1、你的设计是否充分地处理了由系统架构层定义出并且推迟确定的事项?
2、你的设计被划分为层次吗?
3、你对把这一程序分解成为子程序、包和类的方式感到满意吗?
4、你把对这个类分解成为子程序的方法感到满意吗?
5、类与类之间的交互关系是否已设计为最小化了?
6、类和子程序是否被害人设计为能够在其他的系统中重用?
7、程序是不是易于维护?
8、设计是否精简?设计出来的每一部分都绝对必要吗?
9、设计中是否采用了标准的技术?是否避免使用怪异且难以理解的元素?
10、整体而言,你的设计是否有助于最小化偶然性的和本质性的复杂吗?
核对表:类的质量
抽象数据类型
- 你是否把程序中的类都看做是抽象数据类型了?是否从这个角度评估它们的接口了?
抽象
- 类是否有一个中心目的?
- 类的命名是否恰当?其名字是否表达了其中心目的?
- 类的接口是否展现了一致的抽象?
- 类的接口是否是否能让人清楚明白地知道该如何用它?
- 类的接口是否足够抽象,使你能不必顾虑这费用如何实现其服务的?你能把类看做黑盒子吗?
- 类提供的服务是否足够完整,能让其他类无须动用其内部数据?
- 是否已从类中除去无关信息?
- 是否考虑过把类进一步分解为组件类?是否已尽可能将其分解?
- 在修改类时是否维护了其接口的完整性?
封装
- 是否把类的成员的可访问性降到最小?
- 是否避免暴露类中的数据成员?
- 在编程语言所许可的范围内,类是否已尽可能地对其它的类隐藏了自己的实现细节?
- 类是否避免对其使用者,包括其派生类会如何使用它做了假设?
- 类是否不依赖于其他类?它是松散耦合的吗?
继承
- 继承是否只用来建立“是一个/is a”的关系?也就是说,派生类是否遵循了LSP(Liskov替换原则)?
- 类的文档中是否记述了其继承策略?
- 派生类是否避免了“覆盖”不可覆盖的方法?
- 是否把公共的接口、数据和行为都放到了尽可能高的继承层次中了?
- 继承层次是否很浅?
- 基类中所有的数据成员是否都被定义为private而非protected的了?
跟实现相关的其他问题
- 类中是否只有大约七个或更少的数据成员?
- 是否把类直接或间接调用其他类的子程序的数量减到最少?
- 类是否只在绝对必要时才与其他的类相互协作?
- 是否在构造函数中初始化了所有的数据成员?
- 除非拥有经过测量的、创建浅层复本的理由,类是否都被设计为当作深层复本使用?
与语言相关的问题
- 你是否研究过所有编程语言里和类相关的各种特有问题?
核对表:高质量的子程序
大局事项
- 创建子程序的理由充分吗?
- 一个子程序中所有适于单独提出的部分是不是已经被提出到单独的子程序中了?
- 过程的名字中是否使用了强烈、清晰的“动词+宾语”词组?函数的名字是否描述其返回值?
- 子程序的名字是否描述了它所做的全部事情?
- 是否给常用的操作建立了命名规则?
- 子程序是否具有强烈的功能上的内聚性?
- 子程序之间是否有较松的耦合?
- 子程序的长度是否由其功能和逻辑自然决定,而非遵循任何人为的编码标准?
参数传递事宜
- 整体来看,子程序的参数表是否表现出一种具有整体性且一致的接口抽象?
- 子程序参数的排列顺序是否合理?是否与类似的子程序的参数排列顺序相符?
- 接口假定是否已在文档中说明?
- 子程序的参数个数是否没超过7个?
- 是否用到了每一个输入参数?
- 是否用到了每一个输出参数?
- 子程序是否避免了把输入参数用作工作变量?
- 如果子程序是一个函数,那么它是否在所有可能的情况下都能返回一个合法的值?
核对表:防御式编程
一般事宜
- 子程序是否保护自己免遭有害输入数据的破坏?
- 你用断言来说明编程假定吗?其中包括了前条件和后条件吗?
- 断言是否只是用来说明从不应该发生的情况?
- 你是否在架构或高层设计中规定了一组特定的错误处理技术?
- 你是否在架构或高层设计中规定了是让错误处理更倾向于健壮性还是正确性?
- 你是否建立了隔栏来遏制错误可能造成的破坏?是否减少了其他需要关注错误处理的代码的数量?
- 代码中用到的辅助调试的代码了吗?
- 如果需要启用或禁用添加的辅助助手的话,是否无须大动干戈?
- 在防御式编程时引入的代码量是否适宜——既不过多,也不过少?
- 你在开发阶段是否采用了进攻式编程来使错误难以被忽视?
异常
- 你在项目中定义了一套标准化的异常处理方案吗?
- 是否考虑过异常之外的其他替代方案?
- 如果可能的话,是否在局部处理了错误而不是把它当成一个异常抛到外部?
- 代码中是否避免了在构造函数和析构函数中抛出异常?
- 所有的异常是否都与抛出它们的子程序处于同一个抽象层次上?
- 每个异常是否都包含了关于异常发生的所有背景信息?
- 代码中是否没有使用空的catch语句?(或者如果使用空的catch语句确实很合适,那么明确说明了吗?)
安全事宜
- 检查有害输入数据的代码是否也检查了故意的缓冲区溢出,SQL注入、HTML注入、整数溢出以及其他恶意输入数据?
- 是否检查了所有的错误返回码?
- 是否捕获了所有异常?
- 出错消息中是否避免出现有助于攻击者攻入系统所需的信息
思维导图

本文探讨了软件工程的核心在于管理复杂度,强调在设计接口时应考虑易用性和封装性。文章提供了设计实践和核对表,涵盖设计迭代、风险管理和团队审查等方面。此外,还讨论了类的设计质量,包括抽象、封装和继承的原则。在子程序方面,关注了功能内聚、参数管理和防御性编程。最后,提到了防御式编程的策略,如错误处理和异常处理,以增强软件的安全性。
1939

被折叠的 条评论
为什么被折叠?



