はじめてのBarter - beyond design by contract
前に角田さんの「オレンジニュース」で紹介されていて触らなきゃと思って放置していたのですが
今日のartonさんの日記のエントリを読んで少し触ってみた。
メイヤー本にある継承におけるDbCの関係*1まではAspectの結合段階ではチェックしてくれないみたい。
# 実行時にはチェックしてくれるけど。
あと一クラスにpreまたはpostとinvariantを併用するとAspectの結合段階で
てなエラーが出てアウト。これは仕組み的に厳しそうですね。無念だ....
[ajc] C:\eclipse\workspace\Barter-Example\work\com\wikihouse\wildcats0201\barter\example\PersonBarterAspect.java:40
[error] can't determine precedence between two or more pieces of advice that apply to the same join point: method-execution(void com.wikihouse.wildcats0201.barter.example.Person.setName(java.lang.String))
[ajc] C:\eclipse\workspace\Barter-Example\work\com\wikihouse\wildcats0201\barter\example\PersonBarterAspect.java:24
[error] can't determine precedence between two or more pieces of advice that apply to the same join point: method-execution(void com.wikihouse.wildcats0201.barter.example.Person.setName(java.lang.String))
[ajc] C:\eclipse\workspace\Barter-Example\work\com\wikihouse\wildcats0201\barter\example\PersonBarterAspect.java:76
[error] can't determine precedence between two or more pieces of advice that apply to the same join point: method-execution(void com.wikihouse.wildcats0201.barter.example.Person.setName(java.lang.String))
一応、動作したサンプルのコードを置いておきます。(無保証)
動作環境
xdoclet-1.1.2
aspectj-1.2
barter-0.2.0
Person.java
package com.wikihouse.wildcats0201.barter.example;/**
* @barter
*/
public class Person {private String name;
private int age;
private int money;/**
* @barter.pre aName!=null
*/
public void setName(String aName) {
this.name = aName;
}/**
* @barter.post $this.getAge()>=0
*/
public void setAge(int age) {
this.age = age;
}public String getName() {
return this.name;
}public int getAge() {
return this.age;
}/**
* @barter.post $this.getMoney()>=0
*/
public int payMoney() {
this.money = this.money - 100;
return this.money;
}public int getMoney() {
return this.money;
}
public void setMoney(int money) {
this.money = money;
}
}
PersonTest.java
package test.com.wikihouse.wildcats0201.barter.example;import junit.framework.TestCase;
import barter.runtime.impl.BarterAssertionFailed;import com.wikihouse.wildcats0201.barter.example.Person;
public class PersonTest extends TestCase {
public static void main(String[] args) {
junit.textui.TestRunner.run(PersonTest.class);
}public void testSetName() {
Person person = new Person();
person.setName("aaaa");
try {
person.setName(null);
fail();
} catch (BarterAssertionFailed e) {
assertNull(null);
}
}public void testSetAge() {
Person person = new Person();
person.setAge(13);
try {
person.setAge(-1);
fail();
} catch (BarterAssertionFailed e) {
assertNull(null);
}
}
public void testMoney() {
Person person = new Person();
person.setMoney(400);
person.payMoney();
person.payMoney();
person.payMoney();
person.payMoney();
try {
person.payMoney();
fail();
} catch (BarterAssertionFailed e) {
assertNull(null);
}
}
}