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

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

软件维护与演进

  • 软件维护:修复错误、改善性能

  • 运维是软件开发中最困难的工作之一

    • 处理来自用户报告的故障 / 问题

    • 需要代码后

      • 测试所做的修改
      • 回归测试
      • 记录变化
  • 软件演化:对软件进行持续的更新

  • 软件的大部分成本来自于维护阶段

面向可维护性的构建

  • 模块化
  • OO 设计原则
  • OO 设计模式
  • 基于状态的构造技术
  • 表驱动的构造技术
  • 基于语法的构造技术

可维护性指标

可维护性的许多名称

  • Maintainability 可维护性
  • Extensibility 可扩展性
  • Flexibility 灵活性
  • Adaptability 可适应性
  • Manageability 可管理性
  • Supportability 支持性

一些常用的可维护性指标

  • Depth of Inheritance 继承的层次数

    • 层越多越难维护
  • Class Coupling 类之间的耦合度

    • 好的软件设计要求类型和方法应该具有高内聚和低耦合
    • 高耦合表示设计难以重用和维护,因为它与其他类型有许多相互依赖性
  • Unit test coverage 单元测试的覆盖度

  • Cyclomatic Complexity 圈复杂度

    • 圈太复杂不容易被测试
  • Lines of Code 代码行数

    • 行数长的应该被拆分
  • Maintainability Index (MI) 可维护性指数

    • 计算一个介于 0 和 100 之间的索引值,该值表示维护代码的相对容易程度。

模块化设计和模块化原则

评估模块化的五个标准

  • Decomposability (可分解性)

  • Composability (可组合性)

  • Understandability (可理解性)

  • Continuity (可持续性)

    • 发生变化时受影响范围最小
  • Protection (出现异常之后的保护)

    • 出现异常后受影响范围最小

模块化设计的五个规则

  • Direct Mapping (直接映射)
  • Few Interfaces (尽可能少的接口)
  • Small Interfaces (尽可能小的接口)
  • Explicit Interfaces (显式接口)
  • Information Hiding (信息隐藏)

耦合

  • 耦合性是衡量模块之间的依赖性

  • 耦合程度决定因素

    • 模块之间接口的数量
    • 每个接口的复杂性

内聚

  • 内聚是衡量一个模块的功能或责任有多强的关联

    • 如果一个模块的所有元素都在为同一个目标工作,那么这个模块就有很好的内聚

OO Design Principles: SOLID

SOLID:5类设计原则

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

    • 不应有多于1个的原因使得一个类发生变化,否则就拆分开
    • 一个类,一个责任
    • 在这里插入图片描述
  • (OCP) The Open-Closed Principle (面向变化的)开放-封闭原则

    • 对扩展性的开放

      • 模块的行为应是可扩展的,从而该模块可表现出新的行为以满足需求的变化
    • 对修改的封闭

      • 模块自身的代码是不应被修改的
      • 扩展模块行为的一般途径是修改模块的内部实现(修改继承或者委派的类)
      • 如果一个模块不能被修改,那么它通常被认为是具有固定的行为
    • 关键的解决方案:抽象技术

      • 使用继承、组合/委派
    • 在这里插入图片描述

  • (LSP) The Liskov Substitution Principle Liskov替换原则

    • 子类型必须能够替换其基类型
    • 派生类必须能够通过其基类的接口使用,客户端无需了解二者之间的差异
  • (ISP) The Interface Segregation Principle 接口隔离原则

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

    • 不要强迫类来实现他们不能实现的方法

    • 避免“胖”接口

      • 不够聚合
      • 胖接口可分解为多个小的接口
      • 不同的接口向不同的客户端提供服务
      • 客户端只访问自己所需要的接口
    • 在这里插入图片描述

    • 在这里插入图片描述

      • 在这里插入图片描述
  • (DIP) The Dependency Inversion Principle 依赖转置原则

    • 高级别的模块不应该依赖于低级别的模块。两者都应该依赖抽象。

    • 在这里插入图片描述

    • 在这里插入图片描述

语法驱动的构造

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

    • 输入文件有特定格式,程序需读取文件并从中抽取正确的内容
    • 从网络上传输过来的消息,遵循特定的协议
    • 用户在命令行输入的指令,遵循特定的格式
    • 内存中存储的字符串,也有格式需要
  • 使用grammar判断字符串是否合法,并解析成程序里使用的数据结构

    • 从语法产生的数据结构通常是递归数据类型
    • 根据语法,开发一个它的解析器,用于后续的解析

语法的组成部分

  • 终止节点、叶节点

    • 文本串无法再往下扩展
    • 通常表示为字符串
  • 产生式节点,非终止节点

  • 操作符

    • Concatenation 连接

      • x ::= y z x matches y followed by z
    • Repetition 重复

      • x ::= y* x matches zero or more y
    • Union 选择

      • x ::= y | z x matches either y or z
    • […]

      • x ::= [a-c] is equivalent to x ::= ‘a’ | ‘b’ | ‘c’
      • x ::= [aeiou] is equivalent to x ::= ‘a’ | ‘e’ | ‘i’ | ‘o’ | ‘u’
    • [^…]

      • x ::= [^a-c] is equivalent to x ::= ‘d’ | ‘e’ | ‘f’ | …(all other characters)
    • 优先级

      • 后缀运算符 *、?(重复0或1次) 和 +(1次及以上) 具有最高的优先级
      • 其次是连接
      • 最后是选择
      • 括号可以改变优先级

正则语言和正则表达式

  • 正则语法:简化之后可以表达为一个产生式而不包含任何非终止节点

  • 符号

    • . any single character
    • \d any digit, same as [0-9]
    • \s any whitespace character, including space, tab, newline
    • \w any word character, including underscore, same as
    • [a-zA-Z_0-9]
    • ., (, ), *, +, … escapes an operator or special character so that it matches literally

Java中的正则表达式

  • 在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值