软件构造随笔2

软件生命周期与配置管理
1.软件生命周期(Software Development Lifecycle,SDLC)
从无到有:计划、分析、设计、实施、测试、维护
从有到好:更新版本
2.经典的软件过程模型(线性过程/迭代过程)
瀑布模型(线性)、增量过程(线性)、V 字模型(迭代)、原型过程(迭代)、螺旋
模型(迭代)
3.敏捷开发(Agile Development)
通过快速迭代和小规模的持续改进,以快速适应变化。
4.软件配置管理(SCM)和版本控制系统(VCS)
软件配置管理:追踪和控制软件的变化,其核心时版本控制和基线的确立
软件配置项(SCI):软件中发生变化的基本单元(比如文件)
基线(baseline):软件持续变化中的稳定时刻
配置管理数据库(CMDB):存储软件的各配置项随时间发生变化的信息+基线
版本(version):软件的任一特定时刻的形态的唯一编号
本地版本控制系统(Local VCS):仓库存储于开发者本地,无法共享和协作
集中式版本控制系统(Centralized VCS):仓库存储于独立的服务器,支持多人
协作
分布式版本控制系统(Distributed VCS):仓库存储于独立的服务器+每个开发
者的本地,比如 Git。
5.Git
Git 仓库:本地的 CMDB(.git)+工作目录(本地的文件系统)+暂存区(隔离工作目
录和本地的 CMDB)
文件只有三种状态:已修改、已暂存、已提交
Git 的所有操作都是在一个图数据结构(对象图)上进行。
对象图:版本之间的演化关系图,一条边 A->B 表示“在版本 B 的基础之上作变
化,形成了版本 A”
Head 指向了当前分支的当前 commit。
传统的 VCS 存储版本之间的变化(行),而 Git 存储发生变化的文件(而非代码
行),不变化的文件不重复存储
Git add _
Git clone [url]
Git status
Git commit _
Git remote add []
Git push []
Git checkout -b _
Git checkout _
Git merge _
Git branch -d _
PART 2
第 3 章
基本数据类型、对象数据类型
静态类型检查、动态类型检查
Mutable/Immutable
值的改变、引用的改变
防御式拷贝
Snapshot diagram
Specification、前置/后置条件、规约的强度、行为等价性
ADT 操作的四种类型、表示独立性、表示泄露
不变量、表示不变量 RI
表示空间、抽象空间、AF、以注释的形式撰写 AF/RI
接口、抽象类、具体类、继承、重写、多态、重载、泛型
等价性 equals()和==、hashCode()
不可变对象的引用等价性、对象等价性
可变对象的观察等价性、行为等价性

数据类型与类型检验

  1. 数据类型:基本数据类型/对象数据类型
    基本数据类型:只有值,没有 ID;不可变;在栈中分配内存
    对象数据类型:有值有 ID;可变+不可变;在堆中分配内存
    所有对象类型都直接或间接的继承 Object 类。
    基本类型可以通过包装类转换成相应的对象数据类型(通常在容器类使用,
    可以自动完成)。 2.类型检验静态:类型检验/动态类型检验
    静态类型语言(java)/动态类型语言(python)
    静态类型检查:编译阶段,“类型”“格式”的检查
    动态类型检查:运行阶段,“值”的检查
    //整数除 0 动态类型检查会失败,浮点数除 0 会得到无穷结果。
    3.不变性与可变性
    改变一个变量:将该变量指向另一个值的存储空间
    改变一个变量的值:将该变量当前指向的值的存储空间中写入一个新的值
    不变对象:一旦被创建,始终指向同一个值/引用
    final:final 类无法派生子类;final 变量无法改变值/引用;final 方法
    不能被重写
    可变数据可以提高性能,也适合在模块之间共享数据,但也可能会引发潜
    在的威胁,所以在使用不可变数据类型时要注意防御式拷贝。
    4.Snapshot:用于描述程序运行时的内部状态【会画】
    基本类型的值:单线箭头
    对象类型的值:单线箭头+椭圆
    不可变对象:用双线椭圆
    不可变引用:用双线箭头
    5.数组和容器类
    注意 List 迭代器模式时边遍历边删除可能会引起错误。
    6.一些实用的可变数据类型
    容器类的不可变包装类,得到的结果只能看,不能修改,如果对其修改,
    在编译阶段检查不出来,但运行时会出错。
    7.空指针

设计规约
1.方法/函数
参数类型、返回值类型是否匹配,都在编译阶段静态检查完成。
规约+实现
2. 规约
规约刻画了编程人员的任务,明确了“供需双方”的责任,使得程序与客户
端达成一致;方便沟通协作;隔离变化。
行为等价性:“两个方法是否等价”,站在客户端视角看行为等价性
规约结构:前置条件(requires,java 为 param)+后置条件(effects,java
为 return)
前置条件:对客户端的约束,使用时必须满足的条件
后置条件:对开发者的约束,方法结束后必须满足的条件
契约精神:前置条件满足后置条件必须满足;前置条件不满足程序可作任何
对于可变方法,除非在后置条件里声明过,否则方法内部不应该修改输入参
数。
3. 设计规约
规约的强度:前置条件更放松后置条件更严格,则规约更强
确定的规约:给定一个满足前置条件的输入,其输出是唯一的、明确的
欠定的规约:同一个输入可以有多个输出
非确定的规约:同一个输入,多次执行得到的输出可能不同
//把欠定的规约和非确定的统称为非确定的规约
操作式规约:比如,伪代码
声明式规约:,没有内部实现的描述,只有“初-终”状态
规约的设计应该是内聚的、信息丰富的、一定强度的、抽象的等。
检查代价不太大的前置条件通常在实现时需要检查。
是否使用前置条件取决于:check 的代价;方法的使用范围。

抽象数据类型(ADT)
1.抽象和自定义数据类型
抽象类型:强调“作用在数据上的操作”,程序员和用户无需关注数据如何存
储,只需要设计/使用操作即可。
ADT 是由操作定义的,与其内部如何实现无关。
2.数据类型和操作类型的划分
数据类型:可变/不可变
操作:构造器/生产器/观察器/变值器
构造器(Creator):从无到有
生产器(Producer):从有到新
观察器(Observer):观察值
变值器(Mutator):改变对象属性
3.一些例子
4.设计抽象数据类型
“经验法则”。
简洁、一致的操作;足以便利的支持客户的需要;要么针对抽象设计,要么针
对具体设计,不要混合。
5.表示独立性(Representation Independence)
表示独立性:客户端在使用 ADT 时无需考虑其内部如何实现,ADT 内部表示的
变化不应影响外部规约和客户端。
前置条件和后置条件充分刻画了 ADT 的操作,spec 规定了 client 和 implementer 之间的契约,明确了 client 可以依赖哪些内容,implementer 可
以更安全的更改内容。
6.测试 ADT
7.ADT 的不变量(RI)
不变量:程序在任何时候总要为真的一些性质。
checkRep()检查 RI。
表示泄露(Rep exposure)。
8.抽象函数(Abstraction Function,AF)
表示空间®:实现者看到和使用的值空间
抽象空间(A):用户看到和使用的值空间
AF 即两者间的映射关系(满射,未必单射,未必双射)
9.有益的可变性
10.以文档的形式写清 AF、RI、Rep exposure
11.用表示不变量代替前置条件

面向对象的编程(OOP)
1.基本概念:对象、类、继承和方法
类成员变量、类方法(static)
实例成员变量、实例方法
//静态方法无法直接调用非静态成员
2.接口和枚举类
接口中只有方法的定义,没有实现;接口之间可以继承和扩展;一个类可以实
现多个接口;一个接口可以有多个实现类。
实际中更倾向于用接口定义 ADT。
实现接口的类可以拥有比接口更多的方法,但不能少。
3.封装和信息隐藏
使用接口类型声明变量;客户端仅使用接口中定义的方法;客户端代码无法直
接访问属性。
Public 所有均可见;protected 当前类、同一包内、子孙包均可见,其它包不
可见;default 当前类、同一包内可见;private 仅当前类可见。
4.继承和重写
严格继承:子类只能添加新方法,无法重写父类中的方法(用 final 关键字)
重写:方法拥有完全一致的标签,包括方法名、返回值、参数数目、类型和顺
序,实际调用哪个方法,运行时决定;可见性只能增加不能减少。(@Override)
抽象类:至少含有一个抽象方法;不能实例化;继承抽象类的某个子类在实例
化时,所有父类中的抽象方法必须已经实现。
5.多态、子类型和重载
三种类型的多态:特殊多态、参数化多态和子类型多态
特殊多态:一个方法可以有多个重名的实现(重载)
参数列表必须不同。
根据参数列表进行最佳匹配,在编译阶段决定执行哪个方法
参数化多态:一个类型的名字可以代表多个类型(泛型编程)
泛型变量、泛型类、泛型接口、泛型方法(选学)
//
子类型多态:一个变量名字可以代表多个类的实例(子类型)
子类型规约不能弱化父类型的规约。
一定注意 equals()方法里的参数是 Object.
//public Boolean equals(Object o){…}

ADT 和 OOP 中的等价性
1.等价关系
自反、对称、传递
2.三种看待等价性的方式
(1).基于抽象函数 AF 定义 ADT 的等价操作
A 和 b 等价当且仅当 AF(a)=AF(b),即映射到相同的结果。
(2).站在观察者角度
对两个对象调用任何相同的操作,都会得到相同的结果,则认为这两个对象是
等价的。
3.==和 equals()
4.Object contract
5.可变类型的等价性
观察者等价性、行为等价性
//倾向于实现严格的观察者等价性
//对可变类型来说,死刑案行为等价性即可,即指向相同的内存空间,才是相
等的。
//总结:不可变类型一定要重写 equals()和 hashCode(),可变类型一般不需要

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值