@IT情報マネジメント会議室は、2009年4月15日に新システムに移行しました。
新たに書き込みを行う場合には、新しい会議室をご利用ください。
- PR -

契約によるプログラミングについて疑問があります

1
投稿者投稿内容
Ier
常連さん
会議室デビュー日: 2006/02/23
投稿数: 33
投稿日時: 2007-11-16 18:19
はじめまして。つい最近設計分野に興味を持ち始めたIerと申します。
現在 Bertrand Meyer著 のオブジェクト指向入門を読んでいるのですが、
"契約によるプログラミング"の章で疑問に思ったことがいくつかあるので質問があります。
他のサイトでも確認したのですが、契約によるプログラミングとは、

ルーチンが事前条件を表明することでルーチン内部が簡素になり、
冗長な検査を回避し、拡張性や可読性,保守性が護られる。

と読みました。
この文から私は
「事前条件が設けられたルーチンを利用する側(顧客プログラマ側になるのでしょうか?)に、
事前条件を満たすかどうかの検査ロジックを置け」
というように解釈しているのですが、
これだとルーチンを利用する顧客プログラマが複数いた場合に、
重複検査はされないものの、それこそ検査ロジックがそれぞれに散在し、
検査ロジックの"コピペ"を生みかねないのではないか?と疑問に思っています。

そこで質問なのですが、
このような方法は現在の開発現場では当然に行われていることなのでしょうか?
それとも、そもそも上記に書いた私の解釈が間違っているのでしょうか?
よろしくお願いしますm(_ _)m
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2007-11-16 19:27
こんにちは。

引用:

Ierさんの書き込み (2007-11-16 18:19) より:
「事前条件が設けられたルーチンを利用する側(顧客プログラマ側になるのでしょうか?)に、
事前条件を満たすかどうかの検査ロジックを置け」
というように解釈しているのですが、
これだとルーチンを利用する顧客プログラマが複数いた場合に、
重複検査はされないものの、それこそ検査ロジックがそれぞれに散在し、
検査ロジックの"コピペ"を生みかねないのではないか?と疑問に思っています。



「検査ロジック」とはなんでしょう?

表明(assert)で引っかかる(中断する)のは、
契約違反をしているからで、つまり使い方を間違えているなどの
”バグ”だからだと思いますが。
検査するより、バグ修正するべきではないですか?
Anthyhime
ぬし
会議室デビュー日: 2002/09/10
投稿数: 437
投稿日時: 2007-11-16 20:10
引用:

「事前条件が設けられたルーチンを利用する側(顧客プログラマ側になるのでしょうか?)に、
事前条件を満たすかどうかの検査ロジックを置け」
というように解釈しているのですが、


ぜんぜん違います。逆です。
利用される側でそうしろと言ってます。
パラメーターのアサーションは低コストでできる仕組みが今はたくさんあるので、テスト段階でかなりの欠陥を抽出できるようなります。
Ier
常連さん
会議室デビュー日: 2006/02/23
投稿数: 33
投稿日時: 2007-11-16 20:38
返信ありがとうございますm(_ _)m

>Tdnr_Symさん
言葉足らずですみませんでした。
利用される側(表明する側)の、
public void hoge(int foo) {
  assert(isNotNull(foo));
  ...
}

とあった場合、利用する側の
if (isNotNull(bar))
  hoge(bar);
のロジックのことを言ったつもりでした。

>Anthyhimeさん
「事前条件を満たすかどうかの検査ロジックを置け」
という箇所が誤解を招くような文章でした、すみません。
「アサートするのは利用される側で、その事前条件を満たすように利用する側が配慮するべきだ」
と書いたつもりでした。もしかして、これでも逆なのでしょうか?^^;
Anthyhime
ぬし
会議室デビュー日: 2002/09/10
投稿数: 437
投稿日時: 2007-11-16 20:57
そうした意図であれば、コピペといえばコピペですね。
ただそうした動作をJavaやHaskellなどは言語外で簡単にアサーションできるメカニズムを持ちえています。
なのでコードの重複と呼ぶような複雑性を持つことなく簡単にそうした機構を実装できます。なのであまり問題にならないわけです。
ただ注意すべきなのはアサーションマニアとなってアサーションのコーディングやテストによってそもそものプロジェクトの費用を食いつぶすことになってはならないということです。
アサーションはよい習慣でありますが、プロジェクト方針に従って適切に行うべき、ということになるかと思います。
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2007-11-16 21:18
引用:

Ierさんの書き込み (2007-11-16 18:19) より:
この文から私は
「事前条件が設けられたルーチンを利用する側(顧客プログラマ側になるのでしょうか?)に、
事前条件を満たすかどうかの検査ロジックを置け」
というように解釈しているのですが、
これだとルーチンを利用する顧客プログラマが複数いた場合に、
重複検査はされないものの、それこそ検査ロジックがそれぞれに散在し、
検査ロジックの"コピペ"を生みかねないのではないか?と疑問に思っています。


DbC(Design by Contract)ですよね。私は DbC はぜんぜん知らないのですが、「コピペ」はやはりマズいと思います。ただ、これは DbC とは別の話になるのではないだろうか、という思いもします。要は、DbC はただ検査について言っているだけであり、検査の実装を「コピペ」にするかしないかについてまでは言わないのではないでしょうか。

例として、なんでもいいのですが、たとえば Java の Integer#parseInt のようなメソッドを考えたとします。このメソッドは、引数になんでも受け付けて、受け付けできなければ NumberFormatException を throw します。この場合、検査はメソッド内部に持っているので「コピペ」にはなりません。もし、検査をこのメソッドの呼び出し前におこなうようにするとすれば、boolean parseIntAvailable(String) などのようなメソッドをまず呼んでみて、オッケーならば parseInt を呼ぶ、というような感じになるのかもしれません。
どちらのやりかたにするにせよ、やはり、実装時には、検査は共通化すべきでしょう。

--
unibon {B73D0144-CD2A-11DA-8E06-0050DA15BC86}
Ier
常連さん
会議室デビュー日: 2006/02/23
投稿数: 33
投稿日時: 2007-11-16 22:11
Anthyhimeさん、unibonさん。返信ありがとうございます。

Anthyhimeさん
>ただそうした動作をJavaやHaskellなどは言語外で簡単にアサーションできるメカニズムを持ちえています。
こういった技術があるとは知りませんでした。
貴重な情報を教えてくださりありがとうございますm(_ _)m

unibonさん
>検査は共通化すべきでしょう。
他の本になりますが、バリケードという概念を読んだことがあります。
私も検査は共通化するべきだとは思っていたのですが、
契約によるプログラミングを読んで、少し違和感を覚えたので質問させていただきました。
やはり、世間では検査を共通化させるのが一般なのですね。
ありがとうございます。
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2007-11-17 00:00
こんばんは。

引用:

Ierさんの書き込み (2007-11-16 20:38) より:
言葉足らずですみませんでした。
利用される側(表明する側)の、
public void hoge(int foo) {
  assert(isNotNull(foo));
  ...
}

とあった場合、利用する側の
if (isNotNull(bar))
  hoge(bar);
のロジックのことを言ったつもりでした。



まあそういう意味で言うと
最低限の「検査ロジック」は必要ですしょうが、
別に、これと契約プログラミングは関係なくないですか?
契約プログラミングでなくても「検査ロジック」は必要でしょう?

契約プログラミングの目的は、
文書化された「事前条件」「事後条件」「不変条件」(だけ)でなく
コードに埋め込むことによって、条件違反(契約違反・表明違反)を検出して
早期にバグを発見することだと思いますが??

とりあえず、参考になりそうなリンク先を張っておきます。
一歩進んだ話題 Eiffel の利用 7.2 契約プログラミング
JAVA アサーションを使用したプログラミング
表明(Wikipedia)

私にとっての契約プログラミングの例は、「VisualC++のMFC ライブラリのソースコード」ですかね。
ASSERTマクロやCObject::AssertValid()関数などがあり、
誤った使い方をすると、表明違反(Assertion Failure)で止まってしまいます。

1

スキルアップ/キャリアアップ(JOB@IT)