Skip to content

Instantly share code, notes, and snippets.

@wulucxy
Last active April 16, 2021 02:26
Show Gist options
  • Save wulucxy/2abcd18f3a04cae26a355b071e375efd to your computer and use it in GitHub Desktop.
Save wulucxy/2abcd18f3a04cae26a355b071e375efd to your computer and use it in GitHub Desktop.
#dbc #契约式设计
// 示例来源:https://qiita.com/Jxck_/items/defd80843a4beb5fcfc8
# 定义公共的契约调用规则
function contract(rule) {
return function(target, name, descriptor) {
let rule = new Rule(target, name, descriptor);
let original = descriptor.value;
descriptor.value = function() {
if (rule.before) rule.before.apply(rule, arguments);
if (rule.invaliant) rule.invaliant(this);
let result = original.apply(this, arguments);
if (rule.invaliant) rule.invaliant(this);
if (rule.after) rule.after(result);
return result;
}
}
}
# 具体规则
class Rule {
constructor(target, name, descriptor) {
this.target = target;
this.name = name;
this.descriptor = descriptor;
}
// 前置条件
before(i) {
console.log('before', i);
console.assert(i > 0, `arg for ${this.name} should be positive value`);
}
// 后置条件
after(result) {
console.log('after', result);
console.assert(result > 0, `result of ${this.name} should be positive value`);
}
// 不可变式
invaliant(_this) {
console.log('invaliant', _this);
console.assert(_this.current > 0, '`current` should be positive value');
}
}
function main() {
class Counter {
constructor(initial = 0) {
this.current = initial;
}
@contract(Rule)
up(i) {
this.current += i;
return this.current;
}
}
let counter = new Counter(10);
console.log(counter.up(2));
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment