GoogleのCOFOJAライブラリを使用したJavaでの契約プログラミング

画像

に使用されるもの





この手法は、クラスメソッド、ユーザー関数を実行する際の前提条件と事後条件の検証を提供します。



他のチェックと同様に、プログラムの信頼性を高め、入力および出力でのデータの正確性を保証できます。 または、低い値(不適切に使用された場合)。



アサートとは異なり、チェックはランタイムで実行されます。つまり、プログラムの実行中に直接実行され、リリースバージョンに存在します。



この方法の本質は、各サブプログラムで、特定のアクションの実行のために「契約」が締結されることです。 入力および出力データの範囲に制限(条件)を課します。 さらに、「契約」(条件)の実装は厳しく管理されています。









いくつかの時間クラスがあります。 それがアーカイブであり、宇宙全体の機能が彼の仕事に依存しているとします...



クラスにはメソッドがあります:getHours()、getMinutes()、getSeconds()およびsetHours()、setMinutes()、setSeconds()、それぞれ。



それを説明します(言語の構成とメカニズムの一部は省略されているか、簡潔にするために簡略化されています)



class Time<br>{<br> intHOURS;<br> intMINUTES;<br> intSECONDS;<br><br> getHours();<br> {<br> returnHOURS;<br> }<br> <br> getMinutes();<br> {<br> return MINUTES;<br> }<br><br> getSeconds()<br> {<br> return SECONDS;<br> }<br><br> setHours(newHOURS);<br> {<br> HOURS = newHOURS;<br> }<br><br> setMinutes(newMINUTES);<br> {<br> MINUTES = newMINUTES;<br> }<br><br> setSeconds(newSECONDS)<br> {<br> SECONDS = newSECONDS;<br> }<br>}<br> <br> * This source code was highlighted with Source Code Highlighter .







クラスが正しいデータが返されることを保証するために必要である、または(「プログラムの死者は嘘をつかない」の原則に基づいて)動作しません。



これをどのように行うことができますか? データの正確性を確認します。



方法1:集合農場





簡潔にするために、Timeクラスの一部の詳細と繰り返しの構造を省略します。



class Time<br>{<br> getHours();<br> {<br> if (HOURS<0 ||HOURS>23) <br> throw GREAT_Time_Exception ;<br><br> return HOURS;<br> }<br><br> setHours(newHOURS);<br> {<br> if (newHOURS<0 ||newHOURS>23) <br> throw GREAT_Time_Exception ;<br><br> HOURS = newHOURS;<br> }<br>} <br><br> * This source code was highlighted with Source Code Highlighter .







短所:非自明性テスト。 大量のコードを手動で記述する必要があります。 ちょうど今、コントラクトプログラミング手法を適用しようとしました。 しかし、これはPROVAAAAAALです! なんで? さらに調べます。



方法2:既製のエレガントなソリューションを使用します。





Javaは、注釈のメカニズム(コンパイラ、プリプロセッサへの推奨)をサポートしています。メタデータは、プログラムのソースコードにセマンティックに影響を与えることなく追加できます。 彼の行動を変えることなく。 同時に、コード分析、コンパイル、および実行の段階で使用できます。



これは、複数のGoogle従業員(David Morgan、Andreas Leitner、Nhat Minh Le-「Contracts for Java 20%Team」)によって使用されました。 余暇には、彼らは、Java契約でプログラミングするための方法論を実装することができ、プリプロセッサライブラリ注釈COFOJAを開発しました。



Timeクラスで使用してみましょう。



@Contracted // , – IDE <br> class Time<br>{<br> @Ensures ({“result >= 0”,“result <= 23” })<br> getHours();<br> {<br> return HOURS;<br> }<br><br> @Requires ({“newHOURS>= 0”,“newHOURS<= 23” })<br> @Ensures (“HOURS == newHOURS”)<br> // <br> // @Ensures (“getHours()== newHOURS”) <br> setHours(newHOURS);<br> {<br> HOURS = newHOURS;<br> }<br>} <br><br> * This source code was highlighted with Source Code Highlighter .







@Requires-文字通り、「サブルーチンが実行される前に確認する(「条件が満たされる」)」ことを意味します。それ以外の場合は、例外をスローします。



@Ensures-文字通り、「サブプログラムの実行後に確認する(「条件が満たされる」)」



ここでは、 Path1の場合と同様に、メソッドの事前条件事後条件がチェックされていることがわかります。 違いは何ですか? 違いは、2番目のケースではより視覚的で便利なことです。



これらの2つのオプションに加えて、JAVAでこの手法を使用できるようにするかなり多数のライブラリとツールがありますが、それらは古く、サポートされていない/開発されていないか、使用がそれほど便利ではありません。



ライブラリの構成。





com.google.java.contract。* -COFOJAライブラリのメイン名前空間。



次の注釈の実装が含まれています。





@Contracted -IDEのヒントであり、クラスはコントラクトを使用します。



@ Invariant-不変式は、クラスのグローバルプロパティを定義します。このプロパティは、作成後、そのライフ全体を通じて尊重される必要があります。



@Requires-前提条件を定義します-メソッドまたは関数を入力する前に何をすべきか。



@Ensures-事後条件を定義します-メソッドまたは関数を終了した後にtrueになります。



@ThrowEnsures-事後条件チェックの実行時に、指定された例外をスローできます。





探すもの。




@Ensuresおよび@Requiresには、それぞれ1つのメソッドのみを含めることができます。 いくつかの条件を確認する必要がある場合は、{}の条件レコードを使用します。



@Ensures ( { “1”, “ … ”, “N” } )<br><br>@Requires ( { “1”, “ … ”, “N” } )<br> <br> * This source code was highlighted with Source Code Highlighter .







契約が守られない場合(必要な条件の違反)、ライブラリはPreconditionError例外をスローします。これは、キャッチして処理できる前提条件エラーです。



事後条件をチェックするときに、独自の例外を生成することもできます。

これを行うには、 @ ThrowEnsuresアノテーションを使用します。 構文は次のとおりです。



@ThrowEnsures ({ "" , "" })<br><br>@ThrowEnsures ({<br> "1" , "1" ,<br> ...<br> "N" , "N" ,<br> }) <br><br> * This source code was highlighted with Source Code Highlighter .







ユーザーが入力したデータの正確性を確認するために契約を使用しないでください-これは契約の対象外です。 ソフトウェアモジュール間でのみ使用してください。 代わりに、ユーザー入力検証を個別に実装してください。



自動契約管理のためのIDEの構成。





Eclipse *




準備:

  1. cofoja.jarパッケージを(ソースコードからのコンパイルまで)任意の方法でダウンロード/抽出します。
  2. Eclipse IDEを実行して、新しいプロジェクトを作成します。
  3. cofoja.jarファイルをプロジェクトのルートフォルダーにコピーします。




それでは、プロジェクトの構成を始めましょう。



  1. プロジェクト- >プロパティ- > Javaのビルド・パス 、ライブラリのタブ- > [、表示されるウィンドウで、JARを追加cofoja.jarファイルを選択します
  2. この時点で、 Eclipse IDEは契約注釈を認識し始めます。 しかし、それだけではありません。 あなたが外部のプリプロセッサのアノテーションを使用する必要があり、私たちのプロジェクトをコンパイルするのEclipse IDEを指定する必要があります。



    これを行うには、プロジェクトメニューの[プロジェクト] -> [プロパティ ] -> [Javaコンパイラ ] -> [注釈処理 ]に移動し、すべてのチェックマークを付け、2つのキー(プロセッサオプション)を追加(キー)します。



    com.google.java.contract.classpath-ユーザー注釈プロセッサーを備えたファイルへの絶対パス-cofoja.jar

    com.google.java.contract.classoutput-すべてのプロジェクトクラスがコンパイルされるフォルダー( binフォルダー)への絶対パス。







    com.google.java.contract.classpath = C:\ java \ eclipseWorkspace \ JavaContractsTest \ ccofoja.jar

    com.google.java.contract.classoutput = C:\ java \ eclipseWorkspace \ JavaContractsTest \ bin



    [ ファクトリパス]サブカテゴリで、 [プロジェクト固有の設定を有効にする]チェックボックスをオンにしてから、 [ JARを追加 ] -> cofoja.jar注釈プロセッサを選択します。
  3. その後、プロジェクトをコンパイルするときに、構成したばかりの外部注釈プロセッサを使用する必要があります。 しかし、それだけではありません。
  4. 契約の検証でコードを実行するために、仮想マシンのパラメーターを1つ追加します。 これを行うには、 [実行構成]-> [引数]の[ VM引数]フィールドで、次を指定します。 -javaagent:cofoja.jar
  5. 書式:
  6. -javaagent:<Contract_worker_file_name> .jar
  7. できた あなたは、コードを書き始めることができます。 その後、プロジェクトのコンパイル時に、契約の注釈のエラーがIDEで直接発行されます。




NetBeans * **






1. cofoja.jarパッケージを(ソースコードからコンパイルするまで)使用可能な方法でダウンロード/抽出します。



2. NetBeans IDEを実行して、新しいプロジェクトを作成します。



3. cofoja.jarファイルをプロジェクトのルートフォルダーにコピーします。



4.ここで、プロジェクトの構成を開始します。



a。 プロジェクト->プロパティ->ライブラリ



[ コンパイル]、[プロセッサ]、[実行]タブでcofoja.jarファイルを追加します([ JAR追加 ]ボタン)



b。 ビルドに行く- >コンパイル



[ アノテーション処理を有効にする]、[ エディターでアノテーション処理有効にする]のチェックボックスをオンにして、[ 追加 ]ボタンをクリックし、次の行を追加します: com.google.java.contract.classpath



c。 [ 実行 ]タブに移動します

VMオプションで、次を追加します。 -javaagent:cofoja.jar (契約ハンドラーファイルの名前)

書式:

-javaagent:<Contract_worker_file_name> .jar



d。 できた あなたは、コードを書き始めることができます。 その後、プロジェクトのコンパイル時に、契約の注釈のエラーがIDEで直接発行されます。





Javac-注釈付きの手動コンパイル






1. cofoja.jarパッケージを(ソースコードからコンパイルするまで)使用可能な方法でダウンロード/抽出します。



2.コンパイルしようとしているクラスと同じフォルダにcofoja.jarファイルを入れ、またはそれへのフルパスを指定します。



3.コマンドプロンプトで、 javac -cp cofoja.jar MyClass.javaと入力します



コンパイルします。 エラーメッセージがあれば分析し、修正し、再度コンパイルします。



-cpコンパイラスイッチを使用すると、注釈プリプロセッサを指定できます 。 以下は、プログラムクラスのファイル名です。



構文は次のとおりです。

javac -cp <annotation_processorのファイル名> <Class1.java> <ClassN.java>





*注:これを行った後、コンパイラ( JavaBuilder )が見つからないというエラーメッセージが表示された場合は、 javacコンパイラ(JDK \ bin)でディレクトリをPATHシステム変数に追加します。 この変数を変更した後、変更を有効にするには、再起動する必要がありますWindows 2k / XPの場合、Windows 7はこれを必要としません。Linuxでは 、使用するシェルによっては再ログインする必要があります)。



**注: NetBeansにそのようなメニュー項目がない場合は、古いバージョンを使用している可能性があります。 NetBeans 6.9は間違いなく注釈をサポートしています-それをダウンロードして使用してください。



参照資料






All Articles