SC实验二&第三章


title: SC_Lab2和Chapter3
categories: 软件构造笔记
tags: 软件构造笔记

阅读材料来自于MIT的Software Construction课程 Reading 11: Abstraction Functions & Rep Invariants.

要点如下:

·invariant

·representation exposure

·abstraction functions

·representation invariants

The rep invariant will make it easier to catch bugs caused by a corrupted data structure.

Invariants

 一个好的抽象数据型(ADT)的关键:能否preserves its own invariants

Immutability

 看下面的例子

    public class Tweet {
 
    public String author;
    public String text;
    public Date timestamp;

    /**
     * Make a Tweet.
     * @param author    Twitter user who wrote the tweet
     * @param text      text of the tweet
     * @param timestamp date/time when the tweet was sent
     */
    public Tweet(String author, String text, Date timestamp) {
        this.author = author;
        this.text = text;
        this.timestamp = timestamp;
      }
    }

  如何确保Tweet类是不可变的呢?即一旦建立,相关属性不改变。

 威胁之一是客户端能够直接修改这个域。Representation exposure :code outside the class can modify the representation directly.


不过辛亏有privatefinal,官方给出如下解释

The private and public keywords indicate which fields and methods are accessible only within the class and which can be accessed from outside the class. The final keyword also helps by guaranteeing that the fields of this immutable type won’t be reassigned after the object is constructed.


 一种策略就是防御式拷贝(defensive copying)
例如:

    public Date getTimestamp() {
        return new Date(timestamp.getTime());
    }```
 值得注意的是,另一种copy a mutable object is clone(),但是有些问题,暂且不谈。
<br/>
 ```java
    /** @return a list of 24 inspiring tweets, one per hour today */
    public static List<Tweet> tweetEveryHourToday () {
       List<Tweet> list = new ArrayList<Tweet>(); 
       Date date = new Date();
       for (int i = 0; i < 24; i++) {
           date.setHours(i);
           list.add(new Tweet("rbmllr", "keep it up! you can do it", date));
       } 
    return list;
    }```
![](http://web.mit.edu/6.031/www/sp18/classes/11-abstraction-functions-rep-invariants/figures/tweetEveryHourToday.png)
<br/>&emsp;所以不变性又被破坏了,采用一下策略:
```java
    public Tweet(String author, String text, Date timestamp) {
        this.author = author;
        this.text = text;
        this.timestamp = new Date(timestamp.getTime());
    }```
## Immutable wrappers around mutable data types
&emsp;此时,轮到我们的`Collections.unmodifiableList()`亮相。但是一个downside就是得到的所谓的immutability只是在runtime,but not at compile time. Java也不会在你试着`sort()`这个unmodifiable list的时候警告你,反而抛给你一个冷冰冰的异常。
<br/>&emsp;注意阅读练习里面的array相关的problem
# Rep invariant and abstraction function
&emsp;关键不仅仅在于选取两个集合Space,而且在于选取什么的元素为合法,并且怎样将它们对应成抽象的值。
> not only choosing the two spaces... but also deciding which rep values are legal, and how to interpret them as abstract values.

比如根据此图,我们得到下面的映射:![](http://web.mit.edu/6.031/www/sp18/classes/11-abstraction-functions-rep-invariants/figures/charset-af-ri.svg)
以下要点:
<br/>&emsp;**·每一个抽象类都对应有原象**
<br/>&emsp;**·一些抽象类映射前的原象不止一个**
<br/>&emsp;**·而在集合R中并非所有元素都有映射的象**
<br/>&emsp;和实验相关一点,AF就是某个成员变量代表的抽象概念,RI就是对这个成员变量的限制。然而我这个傻子恍然大悟,AF就是"Abstraction functioin",RI即为" Representation invariant"啊!!!
>**抽象函数AF**:R和A之间映射关系的函数,即如何去解 释R中的每一个值为A中的每一个值。 
<br/>**表示不变性RI**:某个具体的“表示”是否是“合法的” 
<br/>&emsp;可将RI看作:所有表示值的一个子集,包含了所有合法的表示值 
<br/> &emsp;也可将RI看作:一个条件,描述了什么是“合法”的表示

<br/>&emsp;从rep values到其所表示的抽象值之间的映射表示如下
>AF: R -> A

 同时也可以用`R → Boolean`的映射表示是否rep value和一个abstract values之间存在着对应关系。如下图所示
![](http://web.mit.edu/6.031/www/sp18/classes/11-abstraction-functions-rep-invariants/figures/charset-norepeats.svg)
&emsp;对于表达值(rep value)而言, RI(r) 为真当且仅当r被AF映射。RI(“a”) = true, RI(“ac”) = true, 并且 RI(“acb”) = true,RI(“aa”) = false and RI(“abbc”) = false.
<br/>&emsp;尽管有着不相同类型的rep value space 和相同的rep invariant,我们可以构建出不同的映射。例如“acgg”表示字符串之间的范围,[a-c][g-g],所以代表的元素是集合set{a,b,c,g}.
<br/>&emsp;对于client of an abstract data type而言,visible and documented的应该为:abstract value space, creators, observes. 而不可见:abstraction function, rep 和 rep invariant.
>Rep invariant is a function from rep values to boolean.

## Checkint the rep invariant
check的特点:
>&emsp;It’s good for an implementer to call `checkRep()` just before returning from a public method of an ADT class.
><br/>&emsp;`checkRep()` asserts the rep invariant.
## No null values in the rep
## Beneficnet mutation
 
# Documenting the AF,RI, and safety from rep exposure
注意,在描述rep invariant and abstraction function的时候,必须注意:
<br/>&emsp;不能仅仅用“域内全员合法”来简简单单概括RI,重要的是explain是如何区分“合法”和“非法”的。
<br/>&emsp;同样的,对于AF而言,仅仅声明“represents a set of charaters"也是不够的。而应该**define precisely how the concrete field values are interpreted**
而根据[同学的解释](http://https://blog.csdn.net/weixin_39643135/article/details/80231152)
>**Rep exposure**<br/>&emsp;java中数据类型分为mutable和immutable的,对前者进行的操作可能会改变其内部数据;而对后者的操作不改变其内部值,而是构造新的对象。因此,对于mutable的数据,如果没有良好的保护,意味着client对其的调用可以直接修改内部数据。
### What an ADT specification may talk about
![](http://web.mit.edu/6.031/www/sp18/classes/11-abstraction-functions-rep-invariants/figures/adt-firewall.svg)
<br/>
# ADT invariants replace preconditions
An invariant is a property of a program that is always true, for every possible runtime state of the program. 
<br/>&emsp;为什么需要不变量? <del>因为爱情。</del>保持程序的“正确性”,容易发现错误。

# 补充
## SPEC
&emsp;SPEC is the abbreviation of the word-specification,规约。client能干什么,不能干什么,输入输出满足的条件将在spec中罗列得清清楚楚。
大致要点
1. Function / method in programming language
1. Specification: Programming for communication 
1. Designing specifications 
<br/>
### Spec Structure

- 前置条件 precondition(对客户端的约束,在使用方法时必须满足的条件)
 >The precondition is an obligation on the client (i.e., the caller of the method). It’s a condition over the state in which the method is invoked. 


- 后置条件 postcondition(后置条件:对开发者的约束,方法结束时必须满足的条件)
 > The postcondition is an obligation on the implementer of the method.  

- – Precondition , indicated by the keyword **requires** 
<br/>– Postcondition , indicated by the keyword **effects**
<br/>相应于`@return`和`@param`呢?来看课件讲义:
<br/>&emsp;Parameters are described by **@param** clauses and results are described by @return and **@throws** clauses. 
<br/>&emsp;Put the preconditions into **@param** where possible, and postconditions into **@return** and **@throws**.
<br/>
### 规约强弱?
<br/>&emsp;规约的强度S2>=S1 A specification S2 is stronger than or equal to a specification S1 if 
- S2’s precondition is weaker than or equal to S1’s  前置条件更弱 
- S2’s postcondition is stronger than or equal to S1’s, for the states that satisfy S1’s precondition. 后置条件更强
<br/>&emsp;简而言之,spec变强就是**更放松的前置条件** + **更严格的后置条件** 

# 漫漫实验路
## -ea
&emsp;多谢橙子的提醒,在poet测试里面需要用到assert断言,而必须要在Eclipse中开启assert选项。[详情](https://blog.csdn.net/styshoo/article/details/48209493)
>Windows -> Preferences ->Java ->Installed JREs ->待使用的JDK ->Edit ->Default VM Arguments文本框中输入:-ea
## 异常测试
&emsp;本人在实验里面经常用到对抛出异常的检测,下面以lab2中Board异常检测为例。Board规定了,应该为"chess"或者"go"类型,而在这里传入"tt"显然会抛出异常的。
```java

	public Board(String type) {
		if(type == "chess")
			N = 8;
		else if(type == "go")
			N = 19;
		else 
			throw new RuntimeException("Not a game that we'll provide for you");
     ...
    }

	/*
	 * Test for exception
	 * */
	@Test(expected = RuntimeException.class)
	public void typeExceptionTest() {
		Board board = new Board("tt");
	}

3.4

区分override 和 overload

 overload用同一个方法名字但是输入不同的参数列表,比如本人在实验中构造的函数

    public Vertex(L source,L target, int weight) {
    	label = source;
        toVertex = new HashMap<L, Integer>();
    	toVertex.put(target, weight);
    }
    public Vertex(L name) {
    	this.label = name;
    	this.toVertex = new HashMap<L, Integer>();
    }

Evan的这篇文章很好:Java 何时需要重写hashCode()和equals()
 此外override在run time检查,而overload是在compile阶段就进行检查

3.5 Equality in ADT and OOP

Equality

 等价关系(Equivalence Relation):自反、对称、传递

Equality in immutable types

  1. a equals b if and only if f(a) = f(b),即AF映射同样的结果。
  2. 站在外部角度,对两个对象调用任何相同操作,都能得到相同结果,认为等价性成立。
    举例:
public class Duration {
    private final int mins;
    private final int secs;
    // Rep invariant:
    //    mins >= 0, secs >= 0
    // Abstraction function:
    //    AF(min, secs) = the span of time of mins minutes and secs seconds

    /** Make a duration lasting for m minutes and s seconds. */
    public Duration(int m, int s) {
        mins = m; secs = s;
    }
    /** @return length of this duration in seconds */
    public long getLength() {
        return mins*60 + secs;
    }
}

其中下列那些等价呢?

Duration d1 = new Duration (1, 2);
Duration d2 = new Duration (1, 3);
Duration d3 = new Duration (0, 62);
Duration d4 = new Duration (1, 2);

区分equals和“==”

 等价性:引用等价性和对象等价性

 对基本数据类型,使用**==**判定相等

 对对象类型,使用equals.

  • == 和内存空间相关。

再看这个例子


public class Duration {
    ...   
    // Problematic definition of equals()
    public boolean equals(Duration that) {
        return this.getLength() == that.getLength();        
    }
}

结果呢

Duration d1 = new Duration (1, 2);
Duration d2 = new Duration (1, 2);
Object o2 = d2;
d1.equals(d2)true
d1.equals(o2)false

 答案为true和false。d2的类型是Duration,而o2的类型是Object,在类Duration里面的equals无法对这个o2进行等价判断。而且o2和d1指向并非同一内存空间,因此会返回false

 上述给的例子是overload而非override。

public class Duration extends Object {
    // explicit method that we declared:
    public boolean equals(Duration that) {
        return this.getLength() == that.getLength();
    }
    // implicit method inherited from Object:
    public boolean equals(Object that) {
        return this == that;
    }
}

 equals三件套:(1)是否为空 (2)类型是否相同 (3)根据AF设计相等判断。但是有一弊处:在没有AF情况下判断每个域的等价性,这是不合理的。

Hashcode

 hashCode -> memory address!!!

 规定一个原则:等价的对象必须有相同的hashCode。(不相等的对象也可以映射为同样的hashCode但性能会变差)

A general rule:
Always override hashCode() when you override equals()

Equals of Mutable Types

 mutable:

  • 观察等价性(在不改变状态情况下,两个对象是否一致)
  • 行为等价性 (调用对象的任何方法都展示出一致的结果)

 对可变类型来说,往往倾向于实现严格的观察等价性(observational equality)。但在某些时候观察等价性可能导致bug甚至可能破坏RI。

immutable类型重写equals和hashCode(),但是mutable类型就不必重写

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源
大学生在线租房平台管理系统按照操作主体分为管理员和用户。管理员的功能包括报修管理、报修评价管理、字典管理、房东管理、房屋管理、房屋收藏管理、房屋留言管理、房屋租赁管理、租房论坛管理、公告信息管理、留言板管理、用户管理、管理员管理。用户的功能等。该系统采用了Mysql数据库,Java语言,Spring Boot框架等技术进行编程实现。 大学生在线租房平台管理系统可以提高大学生在线租房平台信息管理问题的解决效率,优化大学生在线租房平台信息处理流程,保证大学生在线租房平台信息数据的安全,它是一个非常可靠,非常安全的应用程序。 管理员权限操作的功能包括管理公告,管理大学生在线租房平台信息,包括房屋管理,培训管理,报修管理,薪资管理等,可以管理公告。 房屋管理界面,管理员在房屋管理界面中可以对界面中显示,可以对房屋信息的房屋状态进行查看,可以添加新的房屋信息等。报修管理界面,管理员在报修管理界面中查看报修种类信息,报修描述信息,新增报修信息等。公告管理界面,管理员在公告管理界面中新增公告,可以删除公告。公告类型管理界面,管理员在公告类型管理界面查看公告的工作状态,可以对公告的数据进行导出,可以添加新公告的信息,可以编辑公告信息,删除公告信息。
基于hal库的OLED显示屏驱动C语言实现源码.zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值