Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

オブジェクト指向入門8

81 vues

Publié le

ソフトウェア基礎講座資料

Publié dans : Formation
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

オブジェクト指向入門8

  1. 1. オブジェクト指向 プログラミング入門 ソフトウェア基礎講座 第8回 2011年3月31日 服部健太
  2. 2. 2011/3/31 オブジェクト指向プログラミング入門 8 2 契約による設計: 信頼性の高いソフトウェアを構築す る これまでの関心  再利用性,拡張性,互換性  本章での関心  信頼性(正しさと頑丈さ)  ソフトウェアの信頼性を高める手段として, 表明( assertion )と契約による設計 ( Design by Contract )について学ぶ
  3. 3. 2011/3/31 オブジェクト指向プログラミング入門 8 3 基本的な信頼性のメカニズム  ソフトウェアシステムの構造がシンプルで, モジュール性があり , 拡張性のあるアーキテ クチャであること  ソフトウェアをエレガントで読みやすいもの にすること,内容が明瞭かつシンプルである こと  ガーベジコレクションがあること  静的型付け
  4. 4. 2011/3/31 オブジェクト指向プログラミング入門 8 4 ソフトウェアの正しさについて  プログラムが正しいかどうか?という質問に 答えるには,何をするのかを厳密に記述した 仕様書( specification )が必要  ソフトウェアの要素が正しいかどうか,というよ りもむしろ,対応する仕様書と一致するかどうか が問題  仕様書を書くことがソフトウェアの正しさを保証 する第一歩  本章では表明を使った仕様の記述方法について学 ぶ 正しさは相対的な概念である ソフトウェアの正しさの性質
  5. 5. 2011/3/31 オブジェクト指向プログラミング入門 8 5 仕様を書く  正しさの公式(ホーアのトリプル)  {P} A {Q}  A は処理, P は事前条件, Q は事後条件を 表す  例:  {x >= 9} x := x + 5 {x >= 13} 任意の A の実行は, P の状態になったときに始まり, Q の状態になったと きに終了する 正しさの公式の意味  {P} A {Q}
  6. 6. 2011/3/31 オブジェクト指向プログラミング入門 8 6 ホーア論理
  7. 7. 2011/3/31 オブジェクト指向プログラミング入門 8 7 弱い条件と強い条件  強い事前条件ほど,プログラムを書く側に とっては良い,使う側にとっては悪い  {False} A {…}  プログラム A は何でもよい(終了しなくてもよ い)  弱い事後条件ほど,プログラムを書く側に とっては良い,使う側にとっては悪い  {…} A {True}  プログラム A は終了しさえすればよい
  8. 8. 2011/3/31 オブジェクト指向プログラミング入門 8 8 ソフトウェアテキストに表明を導入 する  ソフトウェア要素の正しさは仕様書と実装の 一貫性にある  ⇒ ソフトウェアそのものに実装と仕様の両方を入 れるようにするべきである  仕様を表すために表明を利用する  表明の例:  ある整数は正の値をもつ,ある参照は無効でない, etc.  n > 0; x /= Void
  9. 9. 2011/3/31 オブジェクト指向プログラミング入門 8 9 事前条件と事後条件  事前条件は require 句に書く  そのルーチンが呼ばれるときは必ず保持されなけ ればならない性質  事後条件は ensure 句に書く  そのルーチンがリターンするときに保証しなけれ ばならない性質
  10. 10. 2011/3/31 オブジェクト指向プログラミング入門 8 10 スタッククラスの例 class STACK1[G] feature -- アクセスする count: INTEGER item: G is require not empty do … end feature -- 状態を報告する empty: BOOLEN is do … end full: BOOLEAN is do … end feature – 要素を変更する put (x: G) is require not full do … ensure not empty item = x count = old count + 1 end remove is require not empty do … ensure not full count = old count – 1 end end
  11. 11. 2011/3/31 オブジェクト指向プログラミング入門 8 11 ソフトウェア信頼性のための契約  ルーチンの事前条件と事後条件を定義するということは, ルーチンとそれを呼び出すものの間で契約( contract )を結 んだということである  事前条件は顧客を束縛する  顧客にとっては義務,提供者にとっては利益を意味する  事後条件はクラスを束縛する  顧客にとっては利益,提供者にとっては義務を意味する put 義務 利益 顧客 スタックに空きがある場合にの み, put(x) を呼び出すこと. 次のように更新されたスタックが 得られる.スタックは空ではなく ,最上部に x が追加されている 供給者 次のようにスタックが更新され ていること.最上部に x がある. count が 1 増加する.スタックは 空ではない. スタックに空きがあるという仮定 の下に,シンプルな処理が行なえ る
  12. 12. 2011/3/31 オブジェクト指向プログラミング入門 8 12 検査が少ないほど保証は大きい  x が負の場合を考慮せずに平方根のアルゴリズムを書くことがで きる sqrt(x: REAL): REAL is -- x の平方根 require x >= 0 do … end  ルーチン do 句を以下のように書いてはいけない if x < 0 then “ ”どうにかしてエラーを処理する else “ ”正常な平方根の計算を行なう end どんな事情があっても,ルーチンの事前条件にあたるテストを,ルーチンの 本体で行なってはならない. 非冗長性の原則 シンプルさ が失われる
  13. 13. 2011/3/31 オブジェクト指向プログラミング入門 8 13 表明は入力検査メカニズムにあら ず  契約はルーチン間(契約者と顧客)で取り交わすものである.  あくまでもソフトウェア同士のコミュニケーション  事前条件はユーザ入力の面倒を見るわけではない  次のような形式の事前条件は意味がない. require input >= 0  フィルタモジュールを使う 外部オブジェクト 入力チェックモジュール 処理モジュール
  14. 14. 2011/3/31 オブジェクト指向プログラミング入門 8 14 表明は制御構造にあらず  表明は正しさの条件を表す 実行時の表明違反は,そのソフトウェアにバグがある証拠である 表明違反規則(1) 事前条件違反は顧客側にバグがある証拠である 事後条件違反は供給者側にバグがある証拠である 表明違反規則(2)
  15. 15. 2011/3/31 オブジェクト指向プログラミング入門 8 15 エラー,欠陥,その他,モゾモゾ這 い回るやつ  エラーから欠陥が生じ,フォルトは欠陥によって起 こる.  「バグ」は欠陥の意味を持つことが多い エラー( error )とは,ソフトウェアシステムの開発中になされた誤った決 定である 欠陥( defect )とは,意図した振る舞いからシステムが逸れてしまう原因 となるソフトウェアシステムの特性である フォルト( fault )とは,何らかの実行中に意図した振る舞いから逸れてし まうソフトウェアシステムのイベントである ソフトウェアの災いを表す用語
  16. 16. 2011/3/31 オブジェクト指向プログラミング入門 8 16 例:完全なスタッククラス(1) class STACK2[G] creation make feature -- 初期化する make(n: INTEGER) is -- 最大 n 個の要素分,スタックを割り付ける require positive_capacity: n>= 0 do capacity := n create representation.make(1, capacity) ensure capacity_set: capacity = n array_allocated: representation /= Void stack_empty: empty end
  17. 17. 2011/3/31 オブジェクト指向プログラミング入門 8 17 例:完全なスタッククラス(2) feature -- アクセスする capacity: INTEGER -- スタックの最大要素 count: INTEGER -- スタックの中の要素の数 item: G is -- 最上位の要素 require not_empty: not empty -- すなわち, count > 0 do Result := representation @ count end
  18. 18. 2011/3/31 オブジェクト指向プログラミング入門 8 18 例:完全なスタッククラス(3) feature -- 状態を報告する empty: BOOLEAN is -- スタックは空か? do Result := (count = 0) ensure empty_definition: Result = (count = 0) end full: BOOLEAN is -- スタックはいっぱいか? do Result := (count = capacity) ensure full_definition: Result = (count = capacity) end
  19. 19. 2011/3/31 オブジェクト指向プログラミング入門 8 19 例:完全なスタッククラス(4) feature -- 要素を変更する put(x: G) is -- 最上部に x を加える require not_full: not full -- すなわち, count < capacity do count := count + 1 representation.put(count, x) ensure not_empty: not empty added_to_top: item = x one_more_item: count = old count + 1 in_top_array_entry: representation @ count = x end
  20. 20. 2011/3/31 オブジェクト指向プログラミング入門 8 20 例:完全なスタッククラス(5) remove is -- 最上部の要素を削除する require not_empty: not empty -- すなわち, count > 0 do count := count – 1 ensure not_full: not full one_fewer: count = old count – 1 end feature {NONE} -- 実装する representation: ARRAY[G] -- 配列はスタック要素を保持するのに使われる invariant … …後でこの部分を埋める end
  21. 21. 2011/3/31 オブジェクト指向プログラミング入門 8 21 命令的であることと適用的であるこ と  empty と full の表明  ルーチンの本体と事後条件がほとんど同じ  2つの構成要素の違いは大きく,けっして冗長ではない  命令 Result := (count = capacity) はコンピュータに与える命令である  表明 Result = (count = capacity) は何もしない. 命令 表明 実装( Implementation ) 仕様( Specification ) 命令( Instruction ) 表現( Expression ) どのように( How ) 何を( What ) 命令的( Imperative ) 適用的( Applicative ) 指示的( Prescription ) 記述的( Description )
  22. 22. 2011/3/31 オブジェクト指向プログラミング入門 8 22 空の構造に関する知見  STACK2 の生成プロシージャ make の事前条 件は n >= 0 であった.  空スタックが許される  スタックの put や item では,どちらの事前条件で も,空スタックに対しては常に偽( false )とな る  データ構造設計に際し,それが論理的に不可 能でないならば,空のケースも計画に入れる べきである
  23. 23. 2011/3/31 オブジェクト指向プログラミング入門 8 23 事前条件の設計:保護型か要求型 か?  整合性の条件をどちらに割当てるか?  要求型( demanding ):  顧客に責任を割当てる.この場合,条件はルーチンの事前条 件の一部として表される  保護型( tolerant ):  供給者に責任を割当てる.この場合,条件はルーチン本体に if condition then … 形式の条件文,もしくは同等な制御構造で 表される  再利用性と信頼性にとっては要求型が良い  平方根の例:  x<0 のケースを扱う効果的かつ一般的な方法は存在しない.  この呼び出しが意味するところを知りうるのは顧客だけであ る  ソフトウェアのエラー,0を期待する,例外を引き起こす, etc.
  24. 24. 2011/3/31 オブジェクト指向プログラミング入門 8 24 妥当な事前条件  事前条件で妥当であるケースが存在する場合 にだけ,要求アプローチが適用できる.  ルーチンを実装する供給者の都合上でのみ意味が ある制限は除かれるべき (「要求型」設計アプローチにおいて)すべてのルーチンの事前条件は次の 要求を満足しなければならない  ● 顧客モジュールの作者に配布される公式文書に,事前条件が示されてい な     ければならない  ● その事前条件が必要かどうかは,仕様の観点からでしか判断してはなら ない 妥当な事前条件の原則
  25. 25. 2011/3/31 オブジェクト指向プログラミング入門 8 25 事前条件と公開状態  以下のようなクラスは不正(コンパイルエラーとなる) class SNEAKY feature tricky is require accredited do … end feature {NONE} acredited: BOOLEAN is do … end end  顧客は tricky を呼び出す前に,それが正しいかどうか調べられな い  事後条件にはこのような規則はない ルーチンの事前条件にあるすべての特性は,ルーチンを利用できるすべての 顧客に利用可能でなければならない 事前条件の利用可能性の規則
  26. 26. 2011/3/31 オブジェクト指向プログラミング入門 8 26 クラス不変表明  すべてのルーチンで維持されなければならない,ク ラスインスタンスに共通する全体的な特性  スタックの例:  count は常に 0 から capacity の範囲内でなければならない  0 <= count; count <= capacity  invariant 句で記述する class STACK4[G] creation … feature … invariant count_non_negative: 0 <= count count_bounded: count <= capacity … end
  27. 27. 2011/3/31 オブジェクト指向プログラミング入門 8 27 クラス不変表明の特質  クラス C の不変表明は,すべての「安定した」時点 で, C のすべてのインスタンスが満たさなければな らない表明の集合である.  インスタンスの作成時.つまり, create a か create a.make(…) の実行後.  クラスルーチン r へのすべての修飾された a.r(…) の前後  不変表明はいつも満たされている必要はない  プロシージャ g が仕事をはじめ,目的(その事後表明)に 向かう,その過程では,(その実行が終わる前に不変表明 を再構築する限り)不変表明を破壊しても全く問題ない.
  28. 28. 2011/3/31 オブジェクト指向プログラミング入門 8 28 不変表明を守らなければならないの は誰か?  システムを実行している間に invariant 句が違反して いると判明したとき,それは何を意味するのか?  供給者のエラーを意味する 次の2つの条件が満たされている場合に限り,表明 l は,クラス C の正しい クラス不変表明である.   E1 ● C の生成プロシージャすべてにおいて,属性がデフォルト値の状態 で,事   前条件を満たす引数を使い,その結果, l が成立する.   E2 ● クラスのエクスポートされたルーチンすべてにおいて, l とルーチ ンの事前条件の両方を満たす状態で引数を使い,その結果,引き続き l が成 立している 不変表明規則
  29. 29. 2011/3/31 オブジェクト指向プログラミング入門 8 29 クラスの正しさ  属性のデフォルト値が不変表明を満たさない 場合,生成プロシージャを指定する必要があ る.  不変表明を満たすように属性の値をセットする クラスは,次の場合にのみ,その表明に関して正しい.   C1 ● 生成プロシージャ p で,有効な引数の任意の集合 xp に対して,次 の式が   満たされている {DefaultC and prep(xp)} Bodyp {postp(xp) and INV}   C2 ● すべてのエクスポートルーチン r と有効な引数の任意の集合に対し て,次   の式が満たされている. {prer(xr) and INV} Bodyr {postr(xr) and INV} 定義:クラスの正 しさ
  30. 30. 2011/3/31 オブジェクト指向プログラミング入門 8 30 表明命令  check 命令  計算の決まった段階で,特定の性質が満たされなければならな いことをソフトウェアを書く人に悟らせる  check  assertion_clause1  assertion_clause2  …  assertion_clausen  end  「実行時に,制御がこの命令に及んだときはいつでも,示され た条件が(表示句で示されたように)満たされていなければな らない」  目的  特性の性質が満たされることを自分自身で再確認すること  将来あなたのソフトウェアを読む人に,あなたが拠り所にして いるかセルを明らかにすること
  31. 31. 2011/3/31 オブジェクト指向プログラミング入門 8 31 表明を使う  正しいソフトウェアを書くのを助けるため  デバッグして正しくしようとするのではなく,最 初から正しいコードを書くというアプローチ  文書化支援のため  クラスのショート形式(クラスの概観)に表明が 保持される  自動文書化ツールによって顧客に関係する情報を クラスから抽出する  テスト,デバッグ,品質保証をサポートする ため  ソフトウェアの耐障害性をサポートするため
  32. 32. 2011/3/31 オブジェクト指向プログラミング入門 8 32 実行時に表明を監視する  Eiffel ではコンパイルオプションによって,実行時 の表明の取扱いを設定できる  表明検査レベル  no: 全く表明をチェックしない  require: 事前条件がルーチンの入口で成立することを検査 する  ensure: 事後条件がルーチンの出口で成立することを検査 する  invariant: 修飾された呼び出しに対して,クラス不変表明 が,ルーチンの入口と出口で成立することを検査する  loop: ループ不変表明がすべてのループの繰り返しの前後 で成立することと,変化表明が非負であり,必ず減少する ことを検査する  check: 対応する表明が成立することで, check 命令を実 行する  検査の結果,表明が偽と評価されると例外が発生す
  33. 33. 表明をどのくらい監視するのか?  以下のような考慮の間のトレードオフ  ソフトウェアの正しさをどれくらい信用しているか?  最大限の効率をあげることがどれだけ大事か?  未発見の実行時エラーの結果が深刻になる可能性は?  極端な例:  システムのデバッグ中はすべての監視を有効にする  大規模システムのテストやデバッグに非常に有効  効率重視のアプリケーションで,システムを十分に信 頼している場合はすべての監視を取ってもよいだろう  とはいえ,形式的な証明技術のない状態では,表明を監視す る以外に「」システムを十分に信頼することはめったにでき ない... 2011/3/31 オブジェクト指向プログラミング入門 8 33
  34. 34. 本番稼動時にどの表明レベルを選ぶ か?  ソフトウェアシステムというのは,操作を開始する 前に,信頼できるように作られなければならない.  もしあなたがプロジェクト管理者ならば,製品版の チェックが有効であることを決して開発者に前提と させてはならない.  開発中には,表明チェックが少なくとも事前条件レ ベルで必ず有効になっていることを確かめる.検査 を all に設定して,拡張テストを実行する.開発中 にバグが見つかった場合も all にする.  標準製品版に対しては,チェックなし版かチェック 付き版にするかは,あなたの査定に基づいて決める  もし,チェックなしでいこうと決めた場合でも,少 なくとも事前条件付き版をデリバリに加える. 2011/3/31 オブジェクト指向プログラミング入門 8 34
  35. 35. 検討:間接不変表明効果  参照があるため,オブジェクトの属性が別のオブジェクト の操作によって変更され,不変表明を壊す可能性がある.  例:  クラス A は以下の不変表明句を含むが, B は含まないとする 2011/3/31 オブジェクト指向プログラミング入門 8 35 forward backward (A) (B) OA OB round_trip: (forward /= Void) implies (forward.backward = Current) a1: A; b1:B … create a1; create b1 a1.attach(b1) b1.attach(Void) 「 invariant: 修飾された呼び出しに対して,クラス不変 表明が,ルーチンの入口と出口で成立することを検査 する」の意味
  36. 36. 次回予定  日時: 2011年4月7日(木)13:0 0~14:30  場所: LB 2F/A 会議室  内容:例外処理 2011/3/31 オブジェクト指向プログラミング入門 8 36

×