invariant,中文意思是不变性。是软件构造中ADT相关的一个概念。不变量的意思就是在程序的任何阶段都不会改变的一个抽象的性质举例说明,immutability就是程序中一个典型的不变量。(Immutability is one crucial invariant: once created, an immutable object should always represent the same value, for its entire lifetime)
不变量是由ADT来维护的,所以不依赖于任何的客户端的使用限制,即无论用户第几次使用,怎么使用,这些量的数值都不会发生任何的改变。
不变性是ADT应该具有的最重要性质之一.
为什么要引入和维护不变性
不变性便于我们在使用时做出基本的假设。比如string数据类型,当我们在其周围发现bug的时候,我们不会去深入观察其内部是否出现了问题,因为其保证了不可变这一不变性,我们也相信这一不变性。所以我们就可以肯定不会出现我改了一处,其他变量和模块会连带的变动。当我们自己实现ADT的时候,如果我们无法保证这些不变性,那么我们就无法为使用它的人提供任何保障和假设的依据。
不变性(Invariant),表示泄露(rep exposure),表示独立性(rep independence)
不变性经常是和表示泄露和表示独立性放在一起说明的。他们往往是同时达到的。
表示泄露是对不变性和表示独立性的最大破坏当我们把ADT中的field暴露给client时,我们就不可避免地会引发如下问题:
1,用户直接引用并且修改field中变量,引发invariant的破坏。
2,用户使用field中变量,我们在对于rep进行修改时(我们有时候需要经常对内部的变量进行修改),我们无法做到不影响客户端。(然而由于spec约束,对外接口就可以做到不影响)。
所以无论是有意无意,rep exposure都严重的破坏了我们想要达到的,想要维护的内部属性的不变性。即,我们想要使得表达不可见的目的不仅仅为了防止黑客攻击,还有软件构造这一层次的基本质量要求。
为了保证不变性,我们做到的两件事:使用private替代public修饰符,使得变量对于外界不可见;使用final修饰符保证一旦变量被constructor赋值之后,就不再会被reassign(注意是reassign,意味着不能被重新指派引用,但是这一点我们在之前说过,不代表值一定不变化,取决于数据类型)。
保证immutable,维护invariant
保护Invaraint的最好办法:
1,防御式拷贝(对于所有方法的输入输出都要慎重考虑是否涉及这一层)、
2,返回unmodifiable view。
3,或者最好的是,直接使用immutable类型。