HIT哈工大2019春软件构造笔记Charpter3-3.1

软件构造笔记Chapter3

  • 3.1 Data Type and Type Checking 数据类型与数据类型检验
    • 本节目标
    • 1 Data type in programming languages
    • 2 Static/Dynamic data types
    • 3 Types checking
    • 4 Mutability and Immutability
      • Immutability 不变性 --- 重要的设计原则
    • 5 Snapshot diagram as a code-level, run-time, and moment view
    • 6 Complex data types: Arrays and Collections
    • 7 Useful immutable types
    • NULL references
  • 3.2 Designing Specification 设计规约
    • 本节目标
    • 1 Functions & methods in programming languages
    • 2 Specification:Programming for communication

3.1 Data Type and Type Checking 数据类型与数据类型检验

本节目标

  • 静态类型检查与动态类型检查 — static/dynamic type checking
  • 可变数据类型与不可变数据类型 — mutable/immutable
  • Snapshot图理解数据类型

1 Data type in programming languages

数据类型Type = 数据 + 操作 —— 类比抽象代数中群的定义,也是集合和集合上的二元运算。
变量Variable:用特定的数据类型定义,可以存储满足类型约束的值
对于Java:

  • Primitive types 基本数据类型——int long boolean double char
  • Object types 对象数据类型——String Integer
    HIT哈工大2019春软件构造笔记Charpter3-3.1_第1张图片
    Boxed primitives — 包装基本类型,将基本类型包装为对象类型,通常是在定义Collection时使用它们,是Immutable的,一般情况下不要使用,可以自动转换

2 Static/Dynamic data types

Java是一个静态类型语言,是在编译阶段进行类型检查的。而Python是动态类型检查的语言,是在运行阶段进行类型检查的。每一行没错的Python代码都是可以独立运行的。没错Python就是这么nice!还要什么Java

这里会有一个小疑问:为什么我们在Eclipse/IDEA等各种IDE中敲代码的时候,没有进行编译就有各种报错信息呢?这是因为你每敲出一个代码,它就会自动为你编译,所以我们能够实时的看到各种报错信息。不过这可能也是导致IDE吃内存的原因之一吧。其实我还怀疑过是Java也有解释器的原因…

3 Types checking

  • 静态类型检查 — 在编译时检查,避免了将错误带入到运行阶段,可以提高程序的正确性/健壮性,它能够检查的错误有:

    • 语法错误
    • 类名/函数名错误
    • 参数数目/类型错误
    • 返回值类型错误 — like return “30”; from a function that’s declared to return an int
    • 总之,你在使用IDE时,没有运行前的所有IDE帮你报出的错误都是基于静态类型检查的。
  • 动态类型检查 — 在运行时检查,它能够检查的错误有:

    • 非法的参数值
    • 非法的返回值 — when the specific return value can’t be represented in the type.
    • 越界
    • 空指针
  • 无检查,直接报错
    综上,静态检查是关于“类型”的检查,不关心值;动态检查时关于“值”的检查

4 Mutability and Immutability

改变一个变量:将该变量指向另一个值的存储空间
改变一个变量的值:将该变量当前指向的值的存储空间中写入一个新的值

Immutability 不变性 — 重要的设计原则

Immutable types 不变数据类型,一旦被创建,其中的值不能被改变。如果是引用类型,也可以是不变的,一旦确定了指向的对象,指针就不能再改变。用final来声明,对final的变量检查在静态类型检查中执行

  • final类无法派生子类
  • final变量无法改变值/引用
  • final方法无法被子类重写

一个不可变类型的对象不能修改其中的属性。以下用String结合代码快照图Snapshot来展现:
HIT哈工大2019春软件构造笔记Charpter3-3.1_第2张图片
但是有一种可以改变其中值的String类型,StringBuilder!,同样的来看看快照图
HIT哈工大2019春软件构造笔记Charpter3-3.1_第3张图片

那么有什么区别呢?反正最终内部的值还不是按照我们期望的那样改变了么。但是这是单引用的情况,如果我们有多个引用,那么情况将会变得不一样了。来看看下面这个快照
HIT哈工大2019春软件构造笔记Charpter3-3.1_第4张图片
发现了问题的严重性:如果我们有多个引用指向同一个对象,那么当其中的一个引用修改了这个对象的内部值时,其他的所有引用所指向的值也同时发生了改变。

但是,使用不可变类型时,对其频繁修改会产生大量临时拷贝,需要较多的垃圾回收。可变类型就避免了这种情况。
所以,为什么我们需要不可变类型?所以要什么自行车?

安全!Java是作为一个面向对象语言来设计的,它与C类语言的不同点就是没有指针,更加安全。所以当我们设计软件时,要考虑“折中”

那么怎么避免过多的指向同一个对象的引用产生呢?想象一个场景,这里有一个类,这个类中的属性全都是private的。那么要如何查看这些属性呢?很自然的一个想法就是创建一个public的Observer,返回这个属性就好了。比如:

return this.field

好像没有什么不对。等一下!假设这个属性是Mutable的,这不就是相当于把引用暴露出来了么?用户如果修改了其中的内容,不安全因素就产生了!那么要怎么做呢?

Defensive copying 防御性拷贝——返回给用户一个全新的对象
但是如果你的对象是Immutable的,就不用提供防御性拷贝了

5 Snapshot diagram as a code-level, run-time, and moment view

偷点懒了,这些图不好画,就直接上PPT了
HIT哈工大2019春软件构造笔记Charpter3-3.1_第5张图片
HIT哈工大2019春软件构造笔记Charpter3-3.1_第6张图片
HIT哈工大2019春软件构造笔记Charpter3-3.1_第7张图片
HIT哈工大2019春软件构造笔记Charpter3-3.1_第8张图片

6 Complex data types: Arrays and Collections

7 Useful immutable types

NULL references

3.2 Designing Specification 设计规约

本节目标

  • 理解Spec
  • 前置条件/后置条件/precondition/post-condition
  • 规约之外
  • 陈述式、操作式规约
  • 规约的强度及其比较
  • 如何写出一个好的Spec

1 Functions & methods in programming languages

看一个具体的spec的例子
HIT哈工大2019春软件构造笔记Charpter3-3.1_第9张图片

2 Specification:Programming for communication

Spec是一种客户端与程序员达成一种约定,双方都确定了各自的责任,程序员只负责spec要求中的部分——即完成了正确性的要求,至于spec之外的情况是健壮性的要求。而客户端只需要理解spec即可对程序进行正确调用。

只讲“能做什么”,不讲“怎么实现”
判断两个函数是否行为上等价,通过spec来判断,如果在spec的要求下,两个函数的行为相同,那么它们等价。

precondition前置条件

你可能感兴趣的:(软件构造SC笔记)