软件构造之RI&AF

简要介绍:

RI是表示不变量,如果谁破坏了不变量则引起异常,因此有了RI我们可以更容易地捕捉到由于数据结构破坏而引起的bug。

转换为数学问题,AF(s): R→A,R为内部表示是具体的,A为现实世界的抽象空间,是抽象的。

s的定义域可以理解为RI,不满足RI的元素没有映射到abstract space的像,即RI(s)=false。

RI的保持可以理解为一种条件的判断成立,如a>0…

在写代码的时候,将AF和RI写在rep附近,例:

public class CharSet {
    private String s;
    // Rep invariant:
    //   s contains no repeated characters
    // Abstraction function:
    //   AF(s) = {s[i] | 0 <= i < s.length()}
    ...
}

checkRep

对rep时刻满足RI的检查——private void checkRep()

除了Observer,其他Creator、Producer、Mutator都要在函数结束前调用checkRep函数,因为这些操作都伸入了rep,但在观察者中调用也是锦上添花,所以在一个类的所有操作中都调用一遍checkRep是极好的。

checkRep的编写需要根据RI,更细节的是关于Java的硬条件,即No null values in the rep。这是公认且默认的条件,一般在RI中不用单独强调,但是在编写checkRep函数时要注意到这一点,举个例子

class CharSet {
    //rep
    String s;
    //Rep invarient:
	  //  s.length() is even.
}

//Check that the rep invarient is true
private void checkRep() {
    assert s.length() % 2 == 0;
    ...
}

这样的checkRep就不用单独写assert s.length() != null

因为调用s.length()的时候就会自动检查s非空,如果s没有被检查,那么需要明确地调用assert s≠null进行检查。

When you describe the rep invariant and abstraction function, you must be precise:

  • It is not enough for the RI to be a generic statement like “all fields are valid.” The job of the rep invariant is to explain precisely what makes the field values valid or not.
  • It is not enough for the AF to offer a generic explanation like “represents a set of characters.” The job of the abstraction function is to define precisely how the concrete field values are interpreted. As a function, if we take the documented AF and substitute in actual (legal) field values, we should obtain out a complete description of the single abstract value they represent.

// Immutable type representing a tweet.
public class Tweet {

    private final String author;
    private final String text;
    private final Date timestamp;

    // Rep invariant:
    //   author is a Twitter username (a nonempty string of letters, digits, underscores)
    //   text.length <= 140
    // Abstraction function:
    //   AF(author, text, timestamp) = a tweet posted by author, with content text, 
    //                                 at time timestamp 
    // Safety from rep exposure:
    //   All fields are private;
    //   author and text are Strings, so are guaranteed immutable;
    //   timestamp is a mutable Date, so Tweet() constructor and getTimestamp() 
    //        make defensive copies to avoid sharing the rep's Date object with clients.

    // Operations (specs and method bodies omitted to save space)
    public Tweet(String author, String text, Date timestamp) { ... }
    public String getAuthor() { ... }
    public String getText() { ... }
    public Date getTimestamp() { ... }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值