软件构造心得(6)有关于Invariant的一点说明

13 篇文章 2 订阅
11 篇文章 1 订阅

有关Invariant

概念(notion)

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应该具有的最重要性质之一.

“The most important property of a good abstract data type is that it preserves its own invariants.”

为什么要引入和维护不变性

不变性便于我们在使用时做出基本的假设。比如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,防御式拷贝(对于所有方法的输入输出都要慎重考虑是否涉及这一层)、

“If any of the types are mutable, make sure your implementation doesn’t return direct references to its representation.”

2,返回unmodifiable view。
3,或者最最最好的是,直接使用immutable类型。

不要完全把希望寄托于在spec中约束

client的行为是不可测的(老生常谈)。诚然,有时候一份防御式拷贝的代价也许有时候觉得不可接受。但是其减少的潜在的bug的收益是远大于代价的。

“In the absence of compelling arguments to the contrary, it’s almost always worth it for an abstract data type to guarantee its own invariants, and preventing rep exposure is essential to that.”

使用immutable变量避免所有潜在错误

最后的最后,尽量使用immutable变量,可以完全避免这种错误。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值