0

私は Eiffel 言語でコーディングされた計画ソフトウェアに取り組んでいます。次のコードを作成しましたが、このクラスのルーチンに対してどの種類の事後条件および/または事前条件を指定する必要があるかよくわかりません。

私は Eiffel 言語のマスターではなく、そのキーワードはまだ少しトリッキーで、現在の知識レベルでは理解するのが難しいため、この構文のヒントを提供していただけると助かります。

class TIME
feature -- Initialization
 make (one_hour, one_min, one_sec: NATURAL_8)
 -- Setup ‘hour’, ‘minute’, and ‘seconds’ with
 -- ‘one_hour’, ‘one_min’, and ‘one_sec’, as corresponds.
 require
 do
 hour := one_hour
 minute := one_min
 second := one_sec
 ensure
 end
feature -- Setters
 set_hour (one_hour: NATURAL_8)
 -- Updates `hour' w/ value ‘one_hour’.
 require

 do
 hour := one_hour
 ensure

 end
 set_min (one_min: NATURAL_8)
 -- Updates `minute' w/ value ‘one_min’.
 require
 do
 minute := one_min
 ensure
 end
 set_sec (one_sec: NATURAL_8)
 -- Updates `second' w/ value ‘one_sec’.
 require
 do
 second := one_seg
 ensure
 end
feature -- Operation
 tick
 -- Counts a tick for second cycle, following 24 hr format
 -- During the day, “tick” works as follows
 -- For example, the next second after 07:28:59 would be
 -- 07:29:00. While the next second of 23:59:59
 -- is 00:00:00.
 do
 ensure
 end
feature -- Implementation
 hour: NATURAL_8
 minute: NATURAL_8
 second: NATURAL_8
invariant
 range_hour: hour < 24
 range_minute: minute < 60
 range_second: second < 60
end
4

2 に答える 2

1

これが私が使用するものです:

コンストラクターの場合:

make (one_hour, one_min, one_sec: NATURAL_8)
        -- Setup `hour', `minute', and `seconds' with
        -- `one_hour', `one_min', and `one_sec', as corresponds.
    require
        Hour_Valid: one_hour < 24
        Minute_Valid: one_min < 60
        Second_Valid: one_sec < 60
    do
        hour := one_hour
        minute := one_min
        second := one_sec
    ensure
        Hour_Assing: hour = one_hour
        Minute_Assing: minute = one_min
        Second_Assing: second = one_sec
    end

つまり、前提条件は、引数がクラスのコンテキストで有効であるための要件を示します。それらがすでに不変条件に含まれている場合、なぜそれらの前提条件を設定するのかを尋ねたくなるかもしれません。答えは、どちらも同じ理由ではありません。クラスが (常に) 有効である必要がある状態として、不変条件を参照してください。この不変条件が有効であることを確認する必要があるのは、クラス自体またはその子孫 (ただし、クラスのクライアントではない) だけです。makeつまり、不変条件が有効であることを確認するのは機能の役割であり、機能の呼び出し元の役割ではありませんmake。これで、私が設定した前提条件の理由がわかりましたmake。はい、make不変条件が尊重されていることを確認するのは の役割ですが、make不変条件を尊重したい場合、引数として受け取ることができる値についてクライアントを制限する必要があります。したがって、言い換えると、前提条件「Hour_Valid: one_hour < 24」は、機能「make」が、不変の「range_hour: hour < 24」を尊重できることを確認できることを保証します。

さて、事後条件です。ルーチンの最初の行が 'hour := one_hour' の場合、'Hour_Assing: hour = one_hour' のような事後条件を付けるのは奇妙に感じるかもしれません。ポイントは、クラスを継承しTIMEて実装を変更した場合 (たとえば、1 日の始まりからの秒数などのタイムスタンプを使用する場合)、事後条件の尊重はそれほど些細なことではありませんが、事後条件は引き続き新しいmakeルーチンに適用されます。それら (前提条件と事後条件) をドキュメントとして参照する必要があります。これは、機能の呼び出し元に対してmake、引数が有効である場合、実装が何であれ、それが等しいことone_hourを保証できると言っているようなものです。hourone_hour

ここで、すべてのセッターに同等の事前条件と事後条件を設定します。例えば:

set_hour (one_hour: NATURAL_8)
        -- Updates `hour' with the value ‘one_hour’.
    require
        Hour_Valid: one_hour < 24
    do
        hour := one_hour
    ensure
        Hour_Assign: hour = one_hour
    end

不変条件については、すでにコードに良いものを入れていると思います。したがって、ここではこれ以上の説明は必要ないと思います。最後に、すべてのコントラクト (事前条件、事後条件、および不変条件) をドキュメントとして確認することが非常に重要です。これらはオプションである必要があり、コンパイラがそれらを削除した場合、結果のプログラムはコントラクトを使用したものと同等でなければなりません。デバッグに役立つコード ドキュメントのように参照してください。

于 2016-06-14T16:33:23.387 に答える
0

私は Eiffel の専門家ではありません。私の経験のほとんどは C# CodeContracts から得たものですが、ここまでです。

set_hour 機能の構文例を提供します。うまくいけば、これを例全体に一般化できます。

 set_hour (one_hour: NATURAL_8)
 -- Updates `hour' w/ value ‘one_hour’.
 require
  -- generally you can put here any boolean expression featuring arguments/class variables
  hour_in_range: one_hour < 24 -- the part before : is optional, it's called
  -- a name tag, helps with debugging.
 do
  hour := one_hour
 ensure
  hour_is_set: hour = one_hour -- it may seem excessive, but for verification tool such as automated proovers this information is valuable. 
  hour < 24 -- this one duplicates your invariant, you may or may not want to add contracts like this, depending on your needs/style/etc.
于 2016-06-14T16:19:22.270 に答える