このブログの更新は Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama

メールでのご連絡は hiyama{at}chimaira{dot}org まで。

はじめてのメールはスパムと判定されることがあります。最初は、信頼されているドメインから差し障りのない文面を送っていただけると、スパムと判定されにくいと思います。

参照用 記事

もっと仕様の話(1):かたいことばっかり言ってると…

昨日、仕様の話をしたのだけど、もう少し書いておこうかと。この話題になると長くなりがちですね、ヤッパリ。

昨日より:

とまー、こういう仕様の計算が自由にできたらいいな、と思っているのです。

けれども、

まー、難しいですね、イロイロと。

なんです。

「難しい」という話だけだとつまらないので、楽しそうなこと(?)や少しは現実的な話をすることにします。

実際には1人だけで作業するにしても、仕様を書く(設計)、実装するテストするという3つの立場、役割は区別する必要があります。そうしないと、仕様技術の意義は全然理解できないでしょう。

以下では、仕様を書く人(役割)はあまり考えないで、実装者とテスターについて考えます。-- すごく大事な前提があります。

テスターと実装者のお約束:

  1. 実装者は、仕様に書いてあることは守る。だが、仕様に書いてないことはどのように実装してもよい。
  2. テスターは、仕様に書いてあることと明白に違う動作にはクレームをつける。だが、仕様に書いてないことでトヤカク言ってはいけない

つまり、実装者とテスターは、共通の仕様記述以外の手段では情報交換しないことになります。

が、実際には、実装者とテスターの直接コミュニケーションを断っても、それでも、暗黙の情報が流れてしまいます。

例えば、昨日のエントリーで僕は、Counter, value(), inc()のような名前を使いました。これを見て、「incはインクリメント(increement)のことで、カウンタの値を1増やすのだろう」とだいたいの人は思うわけです。つまり、名前を通じて情報が勝手に流れます。

このことは、名前の付け方が大事であるという教訓を導くと同時に、名前やコメントの印象が「実装とテスト」の役割を曖昧にしてしまう危険性も示唆<しさ>します。

例えば、次の2つの記述文(制約)しかない状況を考えます。


// 制約1
on (value() < 100) receiving {inc();}
emits {valueChanged();}
// 制約2
on (value() >= 100) receiving {inc();}
emits {overflow();}

メッセージ受発信はメソッド呼び出しだとして、次の実装は完全に仕様を満たします。


int value() {
return 1;
}

void inc() {
valueChanged();
}

制約1に従って、inc()が来たらvalueChanged()を発行してます。この実装では、(value() >= 100)という条件が満たされることは絶対にないので、制約2を根拠にクレームされることはあり得ません。つまり、テスターがどんなテストをしようと、クレームを付けられません(完璧!)。

フォーマルな立場からは、「もっと精密に仕様を記述せよ」ということになりますが、そればっかり言うと、仕様技術を誰も使わなくなります。現実的には:

  1. 自然言語記述や、自然言語の意味を利用した伝達を許す。
  2. しかし、形式的記述も併用し、形式的に書かれた仕様の充足は絶対条件とする。

となるでしょうか。

今の例では、第3の仕様記述文として「inc()の後では、value()が返す値が1だけ増える」という自然言語文を加えます。すると、いつでも1ばっかり返している当該の実装はダメということになります。

(続く、が、いつになるかわからない)