4

Java プロジェクトでコントラクトを使用しています。(コントラクト=メソッドの開始時と終了時にチェックを行う)

ジェネリック メソッドのコントラクトを記述する良い方法/パターンがあるかどうか疑問に思っています。例えば:

public abstract class AbstractStringGenerator{
    /**
     * This method must return a new line as it's last char
     * @return string output
     */
     public abstract string generateLine(String input);
}

私が欲しいのは、 の出力がgenerateLineコントラクトを満たしていることを確認する良い方法です (この場合、最後の文字は改行文字でなければなりません)。

私はこれを行うことができると思います(しかし、より良い方法があるのだろうか)。

public abstract class AbstractStringGenerator{

     public string generateLine(String input){
         string result = generateLineHook(input);
         //do contract checking...
         //if new line char is not the last char, then throw contract exception...
         return result;
     }
    /**
     * This method must return a new line as it's last char
     * @return string output
     */
     protected abstract string generateLineHook(String input);
}

これが曖昧すぎないことを願っています。どんな助けでも感謝します。

4

4 に答える 4

3

これは、テンプレート メソッド デザイン パターンを使用する場所のようです。テンプレート メソッド パターンを使用すると、一般的なアルゴリズムを抽象クラスで実装して完成させることができますが、詳細の一部は子クラスで実装できます。

Template メソッドを実装するには:

  • サブクラス化の動作を制御するには、アルゴリズムを完成させる必要があります。サブクラスが final キーワードを介してテンプレート メソッドをオーバーライドできないようにすることで、テンプレートに十分なチェックを実装して、アルゴリズムの不変条件が適切に保持されるようにすることができます。
  • サブクラスが変化する可能性のある動作をオーバーライドできるようにする必要があります。サブクラスはこの動作を完全にオーバーライドでき、そのようなメソッドは通常、親クラスでは抽象的であり、サブクラスがフックを実装できる場所として機能することがよくあります。

Template メソッドは、例で次のように実装できます。

public abstract class AbstractStringGenerator{

     // marked as final. Subclasses cannot override this behavior
     public final String generateLine(String input){
         String result = generateLineHook(input);
         //do contract checking...
         //if new line char is not the last char, then throw contract exception...
         if(!result.endsWith("\n")){
             throw new IllegalStateException("Result from hook does not contain new line");
         }
         return result;
     }
    /**
     * This method must return a new line as it's last char
     * @return string output
     */
     protected abstract string generateLineHook(String input);
}


public class ConcreteStringGenerator{

    /**
     * This method overrides the beh
     * @return string output
     */
     protected String generateLineHook(String input){
         return "blah\n";
     }
}
于 2010-08-18T10:15:50.223 に答える
1

まさにそれです。メソッドを作成し、finalその上で修飾子を使用して、誰もコントラクトを書き換えることができないようにする必要があります。このメソッドでは、コントラクトを確認し、内部メソッド (your generateLineHook(String)) を呼び出します。これ以上行うことはありません。

于 2010-08-18T10:14:12.347 に答える
1

サブクラスがチェックをオーバーライドできないように、パブリックメソッドに「最終」を追加することを忘れないでください。

于 2010-08-18T10:17:46.067 に答える
0

私は定期的にコード コントラクトを使用しますが、コントラクトを作成するのが非常に難しい、明確に定義された自己記述型のメソッドが存在することがあります。

Javaについては知りませんが(iContractなどを使用していると思います)、C#/ Code Contractsでは次のようにします:

Contract.Ensures(result[result.Length-1] == @"\n");

または似たようなもの....

これを行うためのより良い方法があるということで、あなたが何を意味するのかわかりません。

于 2010-08-18T10:15:32.033 に答える