前言
谨以此文记录近日软件构造学习了诸多概念,防止记忆混淆,同时记录一下学习内容,仅为个人想法(怎么感觉和写日记一样
ADT
ADT(Abstract data type),即抽象数据类型,可以简单理解为实现了一组操作的数据类型也许可以这么理解,与基本数据类型不同,抽象数据类型强调作用在数据上的操作,而不是数据的具体表示,需要注意的是,一个抽象数据类型是由它的操作和规约定义的,而不是操作的具体实现
Representation Independence
先说什么是representation(表示),表示可以简单理解为数据成员(域),那么表示独立性是什么?Representation Independence,即表示独立性,是指用户使用ADT时无需考虑内部如何实现,ADT的内部实现发生变化不影响外部规约和客户端。那表示泄露rep exposure又是啥?首先要明确的是,我们编写ADT追求的是表示独立性,避免表示泄露。那到底什么是表示泄露?先看个例子:
public class mySet {
private final Set<String> set = new HashSet<>();
public mySet() {}
public Set<String> getSet() {
return set;
}
public boolean addToSet(String add) {
return set.add(add);
}
}
我们提供了公有方法来给用于往集合里添加元素,然而用户完全可以用下面的方法修改这个集合
mySet s = new myset();
s.getSet().add("Whatever I wanna add");
甚至还能通过remove等一些方法来删除set中的元素,这些修改都能直接反映到我们的mySet类的实例s的set成员中,即mySet类中的表示set被泄露了,用户可以用mySet类以外的方法对mySet实例的set域进行修改。显然,只要我们返回了一个Set<String>
的对象,用户必然可以用java已经实现的方法来对这个对象进行修改,那么我们的问题就转移到怎样让用户的修改无法反映到mySet类的实例中的set域里。为了实现这个目的,我们可以返回set域的拷贝,而不是set域本身,这种方法被称为防御式拷贝:
public Set<String> getSet() {
return new HashSet<>(set);
}
这样用户如果用java自身实现的方法就不能对set域修改了,只能用ADT里实现的修改方法进行修改,这样就防止了表示泄露