验证对象不变量和前后条件
D支持包括当用类继承时合约编程.其可帮助你确认对象状态是否总有效并用正确形参传递对象方法和返回有效值,这儿,我们将看到如何用这些特征及为什么管用.
如何做...
采取如下步骤:
当写一个接口,类,或构,在特征之后立刻加进出块到方法,并也加不变量块到聚集.
把断言放在进块来验证你的前条件.
把断言放在出块来验证你后条件.出块可能带一个实参来访问方法的返回值.
在你方法体前加体关键字但之后加进出块(如它有他们).
在子类,即使他们与父类一样,也用进合约来再断定你的输入要求.
把断言放在不变量块来验证总是真的对象条件.一旦构造器返回,不变量必须有效.
除非你的数据成员可带任何值,使他们私有且仅可通过取器和置器属性来访问.
通过不带-发布开关来构建测试你应用.并运行程序来
代码如下:
它如何工作...
D支持合约编程,由艾菲尔语言激励,带三个构造:方法中的进出块和在对象中的不变量块.
所有合约运行在运行时.在D中今天不可能在编译时运行合约.像其他断定语句,当在发布模式时编译编译合约.
最好用进出块而不是在函数自身内写断言,因为进出块理解继承.当在类中覆盖一个继承方法,必须考虑如下几点:
必须通过(它可通过提供可选检查来弱化前条件)任何一个在继承树上的进块.在一个方法中如果没有进块,假定它接受任何输入,并因此总是通过.因此子类必须再断定他们的输入要求,即使他们与接口一样.
必须通过(它可通过提供附加检查加强后条件)所有在继承树中的出块.
必须通过(它必须尊敬父的不变量)在继承树上的所有对象不变量.
这些规则实现面向对象编程的里氏替代准则;一个子类应总可替代其父类或接口而不破坏代码.当通过其接口用一个对象,仅考虑在块的接口而它必须通过(这是因为接口不知道它要前向到哪个实现).
在D中一个合约在方法上的限制是在出合约中缺少预状态.目前没有简单方法,来变通解决这个限制.相反,关注你的出合约来确保你的返回值独自满足一些要求,比如不是无效.
当前D规范也不允许在抽象类方法上合约(尽管在接口上允许他们).未来可移除这个限制.
因为合约是接口的逻辑部分,当你写一个库,如你选择用他们,你也应该在你D接口文件(一个.di文件,其包含函数原型而不是整个实现体)写你合约.这样,用户或编译器可选择在程序的调试版本中插入他们,即使当用库的发布版本.然而,这次,编译器不保持合约.常见方案是提供你库的调试和发布版本或分发完整源码并让用户自己建造.
领取专属 10元无门槛券
私享最新 技术干货