软件构造学习心得4

第十章面向可维护性的构造技术

10.1评估模块化的五个标准

1.Decomposability (可分解性)

将问题分解为各个可独立解决的子问题

目标:使模块之间的依赖关系显式化和最小化

2.Composability (可组合性)

可容易的将模块组合起来形成新的系统

目标:使模块可在不同的环境下复用

3.Understandability (可理解性)

运行时的不正常将局限于小范围模块内

每个子模块都可被系统设计者容易的理解

4.Continuity (可持续性) ——发生变化时受影响范围最小

规格说明小的变化将只影响一小部分模块,而不会影响整个体系结构

5.Protection (出现异常之后的保护) ——出现异常后受影响范围最小

运行时的不正常将局限于小范围模块内

10.2模块化设计的五项规则

1.Direct Mapping (直接映射)

模块的结构与现实世界中问题领域的结构保持一致

对以下评价标准产生影响

– Continuity (持续性)
– Decomposability (可分解性)

2.Few Interfaces (尽可能少的接口)

模块应尽可能少的与其他模块通讯

对以下评价标准产生影响

Continuity, Protection, Understandability and Composability

可持续性、保护性、可理解性、可组合性
3.Small Interfaces (尽可能小的接口)

如果两个模块通讯,那么它们应交换尽可能少的信息

对以下评价标准产生影响

Continuity and Protection

可持续性和保护性
4.Explicit Interfaces (显式接口)

当A与B通讯时,应明显的发生在A与B的接口之间

对以下评价标准产生影响

Decomposability, Composability, Continuity, Understandability

可分解性、可组合性、可持续性、 可理解性
5.Information Hiding (信息隐藏)

经常可能发生变化的设计决策应尽可能隐藏在抽象接口后面

对以下评价标准产生影响

Continuity可持续性

10.3OO Design Principles: SOLID

1.(SRP) The Single Responsibility Principle 单一责任原则

ADT中不应该有多于1个原因让其发生变化,否则就拆分开
2.(OCP) The Open-Closed Principle 开放-封闭原则

对扩展性的开放,对修改的封闭

这两项常常是冲突的,扩展模块行为的一般途径是修改模块的内部实现

关键的解决方案:抽象技术
3.(LSP) The Liskov Substitution Principle Liskov替换原则

第九章内容
4. (DIP) The Dependency Inversion Principle 依赖转置原则

高层模块不应该依赖于低层模块,二者都应该依赖于抽象。

抽象不应该依赖于实现细节,实现细节应该依赖于抽象
5.(ISP) The Interface Segregation Principle 接口聚合原则

不能强迫客户端依赖于它们不需要的接口:只提供必需的接口

简而言之,大的接口可以分解为多个小接口,客户端只访问自己所需要的端口

实现高内聚,功能单一

总的来看

▪ 抽象(abstraction):模块之间通过抽象隔离开来,将稳定部分和容易
变化部分分开
– LSP:对外界看来,父类和子类是“一样”的;
– DIP:对接口编程,而不是对实现编程,通过抽象接口隔离变化;
– OCP:当需要变化时,通过扩展隐藏在接口之后的子类加以完成,而不要修
改接口本身。
▪ 分离(Separation): Keep It Simple, Stupid (KISS)
– SRP:按责任将大类拆分为多个小类,每个类完成单一职责,规避变化,提
高复用度;
– ISP:将接口拆分为多个小接口,规避不必要的耦合。
▪ 归纳起来:让类保持责任单一、接口稳定。

10.4Grammar-based construction语法驱动的构造

有一类应用,从外部读取文本数据,在应用中做进一步处理。

而对数据的格式又有特定的要求

此时可以用语法判断输入是否合法

三种基本的语法操作

Concatenation 连接x ::= y z

Repetition 重复x ::= y*

Union选择x ::= y | z

其他操作

x ::= y?        x为0或1个y

x ::= y+

x ::= [a-c]        x为a-c其中一个

x ::= [aeiou] is equivalent to x ::= 'a' | 'e' | 'i' | 'o' | 'u'

x ::= [^a-c]        x为除a-c外的一个字母

* ? +优先级最高,连接次之,| 最低

第十一章面向可复用性和可维护性的设计模式

 

第十二章面向正确性与健壮性的软件构造

健壮性:系统在不正常输入或不正常外部环境下仍能够表现正常的程度

正确性:程序按照spec加以执行的能力,是最重要的质量指标

正确性倾向于直接报错(error),健壮性则倾向于容错(fault-tolerance)

对外的接口,倾向于健壮;对内的实现,倾向于正确

Reliability = Robustness + Correctness

正常情况是选择合适的方法,折中取舍

12.1异常和错误

 运行时异常,是程序源代码中引入的故障所造成的,如图中所示,它和error一样,属于unchecked 异常,这种异常通常是在编写阶段无法处理(error或者是编写阶段通过验证可以避免的(RuntimeException

非运行时异常,是程序员无法完全控制的外在问题所导致的,无法避免发生

当要决定是采用checked exception还是uncheckedexception的时候,问一个问题:“如果这种异一旦抛出,client会做怎样的补救?”

– 如果客户端可以通过其他的方法恢复异常,那么采用checked exception;
– 如果客户端对出现的这种异常无能为力,那么采用unchecked exception;
– 异常出现的时候,要做一些试图恢复它的动作而不要仅仅的打印它的信息。

本来catch语句下面是用来做exception handling的,但也可以在catch里抛出异常

这么做的目的是:更改exception的类型,更方便client端获取错误信息并处理

比如用户打开网页中,只需告诉用户打开网页失败而不需要告诉具体原因

当异常抛出时,方法中正常执行的代码被终止,如果异常发生前曾申请过某些资源,那么异常发生后这些资源要被恰当的清理

此时就需要finally,inally部分的代码,是否捕获异常都会被执行

12.2断言Assertions

断言:在开发阶段的代码中嵌入,检验某些“假设”是否成立。若成立,表明程序运行正常,否则表明存在错误

使用断言可以帮程序员尽早发现错误,避免扩散,主要目的是为了在开发阶段调试程序、尽快避免错误

例如防御式编程--检查前置条件

断言与异常

断言主要用于开发阶段,避免引入和帮助发现bug,实际运行阶段,不再使用断言,因为断言会影响程序性能

断言可以保证Correctness

错误/异常处理保证Robustness

使用断言处理“绝不应该发生”的情况

使用异常来处理你“预料到可以发生”的不正常情况

如果来自于自己所写的其他代码,可以使用断言来帮助发现错误(例如post-condition就需要

如果参数来自于外部(不受自己控制),使用异常处理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值