JavaA2Z

KAB-studio > プログラミング > JavaA2Z > 契約による設計とは

契約による設計

日本語 契約による設計
英語 design by contract
ふりがな けいやくによるせっけい
フリガナ ケイヤクニヨルセッケイ

解説

メソッド引数及び戻り値に対して明確な仕様を決め、それに基づいて実装すること。
 
メソッドには、様々な仕様が存在する。
引数nullは不可」「文字列の長さは30以下」「0は不可」「100が渡された時のみ0、それ以外は100を返す」「エラー時にはnullを返す」等。
これらの仕様は、得てして明確には決められない。メソッドの多くは「丁寧に使ってね、変な使い方するとどうなるかわからないよ」という曖昧な仕様の元に作られている。
しかし、それでは少し使い方を間違えただけでバグが生まれ、また、実装の変化等によってそれまで動いていたものが動かなくなる事もある。
 
メソッドの仕様をあらかじめ明確にし、それに基づいて実装することで、バグを減らす方法、それが「契約による設計」である。
メソッドの仕様を「契約事項」とし、その契約をメソッドは必ず守ることとする。
契約はまずドキュメンテーションコメントとして記述し、明確に文書化する。
さらに、プログラム上で実際にその「契約事項」を守らせる。
 
契約事項のチェックの方法のひとつは、assertを用いたアサーションである。
メソッド実装の最初で、まず引数をチェックし、実装の最後で返す戻り値をチェックする。
これらのチェックで、引数戻り値が「契約に違反していないか」を調べる。
メソッド実装及び、メソッド呼び出す側は、その契約を守ってプログラムを組む。守らなかった場合にはAssertionError例外投げられるため、そのプログラムは動かないことになる。
 
もうひとつのチェック方法は、JUnitを用いたテストファーストである。
テストファーストではメソッドに対してあらゆる引数による呼び出しい、その戻り値をチェックすることで、メソッドの契約が守られているかをチェックする。
この、契約事項のチェックをうテストプログラムを先に作成することで、このテストプログラムそのものが「メソッドの契約文書」となり、メソッドが必ず契約を守っていることを約束させることになる。
 
基本的には、「契約による設計」は「意識の問題」である。
メソッド全てに細かい仕様を設けるということは、その仕様を決める時点で工数が掛かるため、多くの現場では推奨されない。たとえ「契約による設計」をうことでプログラムのミスが減り、安全なプログラムを作ることができるため、最終的な工数は減ることになったとしても、それは確約されるものではなく、プロジェクト内での説得理由になりにくい。
さらに、アサーションテストファーストうことの実質的な工数の問題や、仕様変更への対応の難しさに加えて、プログラムで「実際にチェックする」ことへの抵抗もある。
「契約による設計」は「性悪説」に基づいた思想である。「契約による設計」をわない場合、「ちゃんとルールを守って使ってくれる」「使う側が実装を見て配慮してくれる」という「性善説」によって成り立っているのに対し、「契約による設計」では「使う側は何も考えてない」「人はミスをする」という「性悪説」を前提としている。
日本プロジェクトでは基本的に性善説によって全てが成り立ち、馴れ合いの中でプロジェクトが進する。そういった中では「契約による設計」は馴染まない。
 
だが、現実に性善説のプロジェクトはその多くが破綻しており、また、海外によるオフショア開発ではこれまでのプロジェクトの進め方ではうまくいかなくなっている。そういった現場では「契約による設計」が有効に働くだろう。

参考サイト

  • (参考サイトはありません)

(KAB-studioからのおしらせです)

サンプルプログラム(とか)サンプルを別ウィンドウで表示サンプルをクリップボードへコピー(WindowsでIEの場合のみ)

// Sample.java
public class Sample
{
    public static void main( String[] args )
    {
        String string = "100";

        try
        {
            // toInt()メソッドの使用例。
            // まず、toInt()メソッドの引数にnullは渡せないので、
            // nullチェックします。
            if( string != null )
            {
                // そして呼び出します。
                int result = toInt( string );
                System.out.println( result );
                // 100
            }
        }
        catch( NumberFormatException e )
        {
            // 変換できなければNumberFormatException例外が
            // 投げられます
            e.printStackTrace();
        }
    }

    /**
    *   文字列を数値に変換するメソッド。
    *   @param string 数値の文字列形式。nullは不可。変換できない場合NumberFormatExceptionを投げます。
    *   @return 変換後の数値。
    */
    public static int toInt( String string ) throws NumberFormatException
    {
        // 「契約による設計」に基づき、ちゃんとチェックします。
        assert string != null : "nullは不可です。";

        return Integer.parseInt( string );
    }
}
// Sample.java
public class Sample
{
    public static void main( String[] args )
    {
        String string = "100";

        try
        {
            // toInt()メソッドの使用例。
            // まず、toInt()メソッドの引数にnullは渡せないので、
            // nullチェックします。
            if( string != null )
            {
                // そして呼び出します。
                int result = toInt( string );
                System.out.println( result );
                // 100
            }
        }
        catch( NumberFormatException e )
        {
            // 変換できなければNumberFormatException例外が
            // 投げられます
            e.printStackTrace();
        }
    }

    /**
    *   文字列を数値に変換するメソッド。
    *   @param string 数値の文字列形式。nullは不可。変換できない場合NumberFormatExceptionを投げます。
    *   @return 変換後の数値。
    */
    public static int toInt( String string ) throws NumberFormatException
    {
        // 「契約による設計」に基づき、ちゃんとチェックします。
        assert string != null : "nullは不可です。";

        return Integer.parseInt( string );
    }
}

この単語を含むページ

「みだし」に含まれているページ

「解説」に含まれているページ

「サンプルプログラムとか」に含まれているページ

はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
Yahoo!ブックマーク 詳細を表示 users
del.icio.us 登録する RSSに登録
サンプルを別ウィンドウで表示
サンプルをクリップボードへコピー(WindowsでIEの場合のみ)
update:2005/07/21
このページは、Javaプログラミング言語についての用語を網羅した辞書「JavaA2Z」の一ページです。
詳しくは「JavaA2Z」表紙の説明をご覧ください。