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

Más contenido relacionado

Similar a オブジェクト指向入門8

【18-C-3】システムアーキテクチャ構築の実践手法
【18-C-3】システムアーキテクチャ構築の実践手法【18-C-3】システムアーキテクチャ構築の実践手法
【18-C-3】システムアーキテクチャ構築の実践手法
Developers Summit
 

Similar a オブジェクト指向入門8 (20)

Databricksチューニングあれこれ(JEDAI 2023 X‘mas/忘年会 Meetup! LT登壇資料)
Databricksチューニングあれこれ(JEDAI 2023 X‘mas/忘年会 Meetup! LT登壇資料)Databricksチューニングあれこれ(JEDAI 2023 X‘mas/忘年会 Meetup! LT登壇資料)
Databricksチューニングあれこれ(JEDAI 2023 X‘mas/忘年会 Meetup! LT登壇資料)
 
Flutterで単体テストを行う方法とGitHub Actionsを使った自動化
Flutterで単体テストを行う方法とGitHub Actionsを使った自動化Flutterで単体テストを行う方法とGitHub Actionsを使った自動化
Flutterで単体テストを行う方法とGitHub Actionsを使った自動化
 
設計/ドメイン設計(3) 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第25回】
設計/ドメイン設計(3) 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第25回】設計/ドメイン設計(3) 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第25回】
設計/ドメイン設計(3) 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第25回】
 
【18-C-3】システムアーキテクチャ構築の実践手法
【18-C-3】システムアーキテクチャ構築の実践手法【18-C-3】システムアーキテクチャ構築の実践手法
【18-C-3】システムアーキテクチャ構築の実践手法
 
NGINX & OpenShift webinar for Energy Sector
NGINX & OpenShift webinar for Energy SectorNGINX & OpenShift webinar for Energy Sector
NGINX & OpenShift webinar for Energy Sector
 
Migrating tocloudnativeapplicationwithusingelasticapm
Migrating tocloudnativeapplicationwithusingelasticapmMigrating tocloudnativeapplicationwithusingelasticapm
Migrating tocloudnativeapplicationwithusingelasticapm
 
オブジェクト指向入門4
オブジェクト指向入門4オブジェクト指向入門4
オブジェクト指向入門4
 
Team Foundation Server ~ 今を生きるエンジニアのための開発基盤とは 【BPStudy #63】
Team Foundation Server ~ 今を生きるエンジニアのための開発基盤とは 【BPStudy #63】 Team Foundation Server ~ 今を生きるエンジニアのための開発基盤とは 【BPStudy #63】
Team Foundation Server ~ 今を生きるエンジニアのための開発基盤とは 【BPStudy #63】
 
Part 3: サーバーレスとシステム間連携基盤 (製造リファレンス・アーキテクチャ勉強会)
Part 3: サーバーレスとシステム間連携基盤 (製造リファレンス・アーキテクチャ勉強会)Part 3: サーバーレスとシステム間連携基盤 (製造リファレンス・アーキテクチャ勉強会)
Part 3: サーバーレスとシステム間連携基盤 (製造リファレンス・アーキテクチャ勉強会)
 
iOSやAndroidアプリ開発のGoodPractice
iOSやAndroidアプリ開発のGoodPracticeiOSやAndroidアプリ開発のGoodPractice
iOSやAndroidアプリ開発のGoodPractice
 
ADO.NET Entity Framework
ADO.NET Entity Framework ADO.NET Entity Framework
ADO.NET Entity Framework
 
AWS Amplify - Auth/API Category & Vue 構築ハンズオン
AWS Amplify - Auth/API Category & Vue 構築ハンズオンAWS Amplify - Auth/API Category & Vue 構築ハンズオン
AWS Amplify - Auth/API Category & Vue 構築ハンズオン
 
23 tm1 performancemodeler
23 tm1 performancemodeler23 tm1 performancemodeler
23 tm1 performancemodeler
 
Smart Store サーバーレスアーキテクチャ編
Smart Store サーバーレスアーキテクチャ編Smart Store サーバーレスアーキテクチャ編
Smart Store サーバーレスアーキテクチャ編
 
20190514 Smart Store - Azure servlerless architecture
20190514 Smart Store - Azure servlerless architecture20190514 Smart Store - Azure servlerless architecture
20190514 Smart Store - Azure servlerless architecture
 
市場動向並びに弊社製品の今後の展望について
市場動向並びに弊社製品の今後の展望について市場動向並びに弊社製品の今後の展望について
市場動向並びに弊社製品の今後の展望について
 
Qlik TECHTALK Qlik Cloud 日本リージョン開設!テナント作成と移行方法を解説
Qlik TECHTALK Qlik Cloud 日本リージョン開設!テナント作成と移行方法を解説Qlik TECHTALK Qlik Cloud 日本リージョン開設!テナント作成と移行方法を解説
Qlik TECHTALK Qlik Cloud 日本リージョン開設!テナント作成と移行方法を解説
 
最先端NLP勉強会2017_ACL17
最先端NLP勉強会2017_ACL17最先端NLP勉強会2017_ACL17
最先端NLP勉強会2017_ACL17
 
Beginners guidetoconceptualmodelingbyuml
Beginners guidetoconceptualmodelingbyumlBeginners guidetoconceptualmodelingbyuml
Beginners guidetoconceptualmodelingbyuml
 
Angularreflex20141210
Angularreflex20141210Angularreflex20141210
Angularreflex20141210
 

Más de Kenta Hattori

Más de Kenta Hattori (20)

オブジェクト指向入門2
オブジェクト指向入門2オブジェクト指向入門2
オブジェクト指向入門2
 
オブジェクト指向入門1
オブジェクト指向入門1オブジェクト指向入門1
オブジェクト指向入門1
 
オブジェクト指向入門10
オブジェクト指向入門10オブジェクト指向入門10
オブジェクト指向入門10
 
オブジェクト指向入門9
オブジェクト指向入門9オブジェクト指向入門9
オブジェクト指向入門9
 
オブジェクト指向入門7
オブジェクト指向入門7オブジェクト指向入門7
オブジェクト指向入門7
 
オブジェクト指向入門5
オブジェクト指向入門5オブジェクト指向入門5
オブジェクト指向入門5
 
オブジェクト指向入門3
オブジェクト指向入門3オブジェクト指向入門3
オブジェクト指向入門3
 
ソフトウェア・テスト入門2
ソフトウェア・テスト入門2ソフトウェア・テスト入門2
ソフトウェア・テスト入門2
 
ソフトウェア・テスト入門1
ソフトウェア・テスト入門1ソフトウェア・テスト入門1
ソフトウェア・テスト入門1
 
ソフトウェア・テスト入門8
ソフトウェア・テスト入門8ソフトウェア・テスト入門8
ソフトウェア・テスト入門8
 
ソフトウェア・テスト入門7
ソフトウェア・テスト入門7ソフトウェア・テスト入門7
ソフトウェア・テスト入門7
 
ソフトウェア・テスト入門6
ソフトウェア・テスト入門6ソフトウェア・テスト入門6
ソフトウェア・テスト入門6
 
ソフトウェア・テスト入門5
ソフトウェア・テスト入門5ソフトウェア・テスト入門5
ソフトウェア・テスト入門5
 
ソフトウェア・テスト入門4
ソフトウェア・テスト入門4ソフトウェア・テスト入門4
ソフトウェア・テスト入門4
 
ソフトウェア・テスト入門3
ソフトウェア・テスト入門3ソフトウェア・テスト入門3
ソフトウェア・テスト入門3
 
アルゴリズムとデータ構造15
アルゴリズムとデータ構造15アルゴリズムとデータ構造15
アルゴリズムとデータ構造15
 
アルゴリズムとデータ構造14
アルゴリズムとデータ構造14アルゴリズムとデータ構造14
アルゴリズムとデータ構造14
 
アルゴリズムとデータ構造13
アルゴリズムとデータ構造13アルゴリズムとデータ構造13
アルゴリズムとデータ構造13
 
アルゴリズムとデータ構造12
アルゴリズムとデータ構造12アルゴリズムとデータ構造12
アルゴリズムとデータ構造12
 
アルゴリズムとデータ構造11
アルゴリズムとデータ構造11アルゴリズムとデータ構造11
アルゴリズムとデータ構造11
 

Último

TokyoTechGraduateExaminationPresentation
TokyoTechGraduateExaminationPresentationTokyoTechGraduateExaminationPresentation
TokyoTechGraduateExaminationPresentation
YukiTerazawa
 
The_Five_Books_Overview_Presentation_2024
The_Five_Books_Overview_Presentation_2024The_Five_Books_Overview_Presentation_2024
The_Five_Books_Overview_Presentation_2024
koheioishi1
 

Último (8)

TokyoTechGraduateExaminationPresentation
TokyoTechGraduateExaminationPresentationTokyoTechGraduateExaminationPresentation
TokyoTechGraduateExaminationPresentation
 
The_Five_Books_Overview_Presentation_2024
The_Five_Books_Overview_Presentation_2024The_Five_Books_Overview_Presentation_2024
The_Five_Books_Overview_Presentation_2024
 
生成AIの回答内容の修正を課題としたレポートについて:お茶の水女子大学「授業・研究における生成系AIの活用事例」での講演資料
生成AIの回答内容の修正を課題としたレポートについて:お茶の水女子大学「授業・研究における生成系AIの活用事例」での講演資料生成AIの回答内容の修正を課題としたレポートについて:お茶の水女子大学「授業・研究における生成系AIの活用事例」での講演資料
生成AIの回答内容の修正を課題としたレポートについて:お茶の水女子大学「授業・研究における生成系AIの活用事例」での講演資料
 
東京工業大学 環境・社会理工学院 建築学系 大学院入学入試・進学説明会2024_v2
東京工業大学 環境・社会理工学院 建築学系 大学院入学入試・進学説明会2024_v2東京工業大学 環境・社会理工学院 建築学系 大学院入学入試・進学説明会2024_v2
東京工業大学 環境・社会理工学院 建築学系 大学院入学入試・進学説明会2024_v2
 
次世代機の製品コンセプトを描く ~未来の機械を創造してみよう~
次世代機の製品コンセプトを描く ~未来の機械を創造してみよう~次世代機の製品コンセプトを描く ~未来の機械を創造してみよう~
次世代機の製品コンセプトを描く ~未来の機械を創造してみよう~
 
ゲーム理論 BASIC 演習106 -価格の交渉ゲーム-#ゲーム理論 #gametheory #数学
ゲーム理論 BASIC 演習106 -価格の交渉ゲーム-#ゲーム理論 #gametheory #数学ゲーム理論 BASIC 演習106 -価格の交渉ゲーム-#ゲーム理論 #gametheory #数学
ゲーム理論 BASIC 演習106 -価格の交渉ゲーム-#ゲーム理論 #gametheory #数学
 
2024年度 東京工業大学 工学院 機械系 大学院 修士課程 入試 説明会 資料
2024年度 東京工業大学 工学院 機械系 大学院 修士課程 入試 説明会 資料2024年度 東京工業大学 工学院 機械系 大学院 修士課程 入試 説明会 資料
2024年度 東京工業大学 工学院 機械系 大学院 修士課程 入試 説明会 資料
 
世界を変えるクレーンを生み出そう! 高知エンジニアリングキャンプ2024プログラム
世界を変えるクレーンを生み出そう! 高知エンジニアリングキャンプ2024プログラム世界を変えるクレーンを生み出そう! 高知エンジニアリングキャンプ2024プログラム
世界を変えるクレーンを生み出そう! 高知エンジニアリングキャンプ2024プログラム
 

オブジェクト指向入門8

  • 2. 2011/3/31 オブジェクト指向プログラミング入門 8 2 契約による設計: 信頼性の高いソフトウェアを構築す る これまでの関心  再利用性,拡張性,互換性  本章での関心  信頼性(正しさと頑丈さ)  ソフトウェアの信頼性を高める手段として, 表明( assertion )と契約による設計 ( Design by Contract )について学ぶ
  • 3. 2011/3/31 オブジェクト指向プログラミング入門 8 3 基本的な信頼性のメカニズム  ソフトウェアシステムの構造がシンプルで, モジュール性があり , 拡張性のあるアーキテ クチャであること  ソフトウェアをエレガントで読みやすいもの にすること,内容が明瞭かつシンプルである こと  ガーベジコレクションがあること  静的型付け
  • 4. 2011/3/31 オブジェクト指向プログラミング入門 8 4 ソフトウェアの正しさについて  プログラムが正しいかどうか?という質問に 答えるには,何をするのかを厳密に記述した 仕様書( specification )が必要  ソフトウェアの要素が正しいかどうか,というよ りもむしろ,対応する仕様書と一致するかどうか が問題  仕様書を書くことがソフトウェアの正しさを保証 する第一歩  本章では表明を使った仕様の記述方法について学 ぶ 正しさは相対的な概念である ソフトウェアの正しさの性質
  • 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}
  • 7. 2011/3/31 オブジェクト指向プログラミング入門 8 7 弱い条件と強い条件  強い事前条件ほど,プログラムを書く側に とっては良い,使う側にとっては悪い  {False} A {…}  プログラム A は何でもよい(終了しなくてもよ い)  弱い事後条件ほど,プログラムを書く側に とっては良い,使う側にとっては悪い  {…} A {True}  プログラム A は終了しさえすればよい
  • 8. 2011/3/31 オブジェクト指向プログラミング入門 8 8 ソフトウェアテキストに表明を導入 する  ソフトウェア要素の正しさは仕様書と実装の 一貫性にある  ⇒ ソフトウェアそのものに実装と仕様の両方を入 れるようにするべきである  仕様を表すために表明を利用する  表明の例:  ある整数は正の値をもつ,ある参照は無効でない, etc.  n > 0; x /= Void
  • 9. 2011/3/31 オブジェクト指向プログラミング入門 8 9 事前条件と事後条件  事前条件は require 句に書く  そのルーチンが呼ばれるときは必ず保持されなけ ればならない性質  事後条件は ensure 句に書く  そのルーチンがリターンするときに保証しなけれ ばならない性質
  • 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. 2011/3/31 オブジェクト指向プログラミング入門 8 11 ソフトウェア信頼性のための契約  ルーチンの事前条件と事後条件を定義するということは, ルーチンとそれを呼び出すものの間で契約( contract )を結 んだということである  事前条件は顧客を束縛する  顧客にとっては義務,提供者にとっては利益を意味する  事後条件はクラスを束縛する  顧客にとっては利益,提供者にとっては義務を意味する put 義務 利益 顧客 スタックに空きがある場合にの み, put(x) を呼び出すこと. 次のように更新されたスタックが 得られる.スタックは空ではなく ,最上部に x が追加されている 供給者 次のようにスタックが更新され ていること.最上部に x がある. count が 1 増加する.スタックは 空ではない. スタックに空きがあるという仮定 の下に,シンプルな処理が行なえ る
  • 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. 2011/3/31 オブジェクト指向プログラミング入門 8 13 表明は入力検査メカニズムにあら ず  契約はルーチン間(契約者と顧客)で取り交わすものである.  あくまでもソフトウェア同士のコミュニケーション  事前条件はユーザ入力の面倒を見るわけではない  次のような形式の事前条件は意味がない. require input >= 0  フィルタモジュールを使う 外部オブジェクト 入力チェックモジュール 処理モジュール
  • 14. 2011/3/31 オブジェクト指向プログラミング入門 8 14 表明は制御構造にあらず  表明は正しさの条件を表す 実行時の表明違反は,そのソフトウェアにバグがある証拠である 表明違反規則(1) 事前条件違反は顧客側にバグがある証拠である 事後条件違反は供給者側にバグがある証拠である 表明違反規則(2)
  • 15. 2011/3/31 オブジェクト指向プログラミング入門 8 15 エラー,欠陥,その他,モゾモゾ這 い回るやつ  エラーから欠陥が生じ,フォルトは欠陥によって起 こる.  「バグ」は欠陥の意味を持つことが多い エラー( error )とは,ソフトウェアシステムの開発中になされた誤った決 定である 欠陥( defect )とは,意図した振る舞いからシステムが逸れてしまう原因 となるソフトウェアシステムの特性である フォルト( fault )とは,何らかの実行中に意図した振る舞いから逸れてし まうソフトウェアシステムのイベントである ソフトウェアの災いを表す用語
  • 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. 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. 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. 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. 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. 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. 2011/3/31 オブジェクト指向プログラミング入門 8 22 空の構造に関する知見  STACK2 の生成プロシージャ make の事前条 件は n >= 0 であった.  空スタックが許される  スタックの put や item では,どちらの事前条件で も,空スタックに対しては常に偽( false )とな る  データ構造設計に際し,それが論理的に不可 能でないならば,空のケースも計画に入れる べきである
  • 23. 2011/3/31 オブジェクト指向プログラミング入門 8 23 事前条件の設計:保護型か要求型 か?  整合性の条件をどちらに割当てるか?  要求型( demanding ):  顧客に責任を割当てる.この場合,条件はルーチンの事前条 件の一部として表される  保護型( tolerant ):  供給者に責任を割当てる.この場合,条件はルーチン本体に if condition then … 形式の条件文,もしくは同等な制御構造で 表される  再利用性と信頼性にとっては要求型が良い  平方根の例:  x<0 のケースを扱う効果的かつ一般的な方法は存在しない.  この呼び出しが意味するところを知りうるのは顧客だけであ る  ソフトウェアのエラー,0を期待する,例外を引き起こす, etc.
  • 24. 2011/3/31 オブジェクト指向プログラミング入門 8 24 妥当な事前条件  事前条件で妥当であるケースが存在する場合 にだけ,要求アプローチが適用できる.  ルーチンを実装する供給者の都合上でのみ意味が ある制限は除かれるべき (「要求型」設計アプローチにおいて)すべてのルーチンの事前条件は次の 要求を満足しなければならない  ● 顧客モジュールの作者に配布される公式文書に,事前条件が示されてい な     ければならない  ● その事前条件が必要かどうかは,仕様の観点からでしか判断してはなら ない 妥当な事前条件の原則
  • 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. 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. 2011/3/31 オブジェクト指向プログラミング入門 8 27 クラス不変表明の特質  クラス C の不変表明は,すべての「安定した」時点 で, C のすべてのインスタンスが満たさなければな らない表明の集合である.  インスタンスの作成時.つまり, create a か create a.make(…) の実行後.  クラスルーチン r へのすべての修飾された a.r(…) の前後  不変表明はいつも満たされている必要はない  プロシージャ g が仕事をはじめ,目的(その事後表明)に 向かう,その過程では,(その実行が終わる前に不変表明 を再構築する限り)不変表明を破壊しても全く問題ない.
  • 28. 2011/3/31 オブジェクト指向プログラミング入門 8 28 不変表明を守らなければならないの は誰か?  システムを実行している間に invariant 句が違反して いると判明したとき,それは何を意味するのか?  供給者のエラーを意味する 次の2つの条件が満たされている場合に限り,表明 l は,クラス C の正しい クラス不変表明である.   E1 ● C の生成プロシージャすべてにおいて,属性がデフォルト値の状態 で,事   前条件を満たす引数を使い,その結果, l が成立する.   E2 ● クラスのエクスポートされたルーチンすべてにおいて, l とルーチ ンの事前条件の両方を満たす状態で引数を使い,その結果,引き続き l が成 立している 不変表明規則
  • 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. 2011/3/31 オブジェクト指向プログラミング入門 8 30 表明命令  check 命令  計算の決まった段階で,特定の性質が満たされなければならな いことをソフトウェアを書く人に悟らせる  check  assertion_clause1  assertion_clause2  …  assertion_clausen  end  「実行時に,制御がこの命令に及んだときはいつでも,示され た条件が(表示句で示されたように)満たされていなければな らない」  目的  特性の性質が満たされることを自分自身で再確認すること  将来あなたのソフトウェアを読む人に,あなたが拠り所にして いるかセルを明らかにすること
  • 31. 2011/3/31 オブジェクト指向プログラミング入門 8 31 表明を使う  正しいソフトウェアを書くのを助けるため  デバッグして正しくしようとするのではなく,最 初から正しいコードを書くというアプローチ  文書化支援のため  クラスのショート形式(クラスの概観)に表明が 保持される  自動文書化ツールによって顧客に関係する情報を クラスから抽出する  テスト,デバッグ,品質保証をサポートする ため  ソフトウェアの耐障害性をサポートするため
  • 32. 2011/3/31 オブジェクト指向プログラミング入門 8 32 実行時に表明を監視する  Eiffel ではコンパイルオプションによって,実行時 の表明の取扱いを設定できる  表明検査レベル  no: 全く表明をチェックしない  require: 事前条件がルーチンの入口で成立することを検査 する  ensure: 事後条件がルーチンの出口で成立することを検査 する  invariant: 修飾された呼び出しに対して,クラス不変表明 が,ルーチンの入口と出口で成立することを検査する  loop: ループ不変表明がすべてのループの繰り返しの前後 で成立することと,変化表明が非負であり,必ず減少する ことを検査する  check: 対応する表明が成立することで, check 命令を実 行する  検査の結果,表明が偽と評価されると例外が発生す
  • 33. 表明をどのくらい監視するのか?  以下のような考慮の間のトレードオフ  ソフトウェアの正しさをどれくらい信用しているか?  最大限の効率をあげることがどれだけ大事か?  未発見の実行時エラーの結果が深刻になる可能性は?  極端な例:  システムのデバッグ中はすべての監視を有効にする  大規模システムのテストやデバッグに非常に有効  効率重視のアプリケーションで,システムを十分に信 頼している場合はすべての監視を取ってもよいだろう  とはいえ,形式的な証明技術のない状態では,表明を監視す る以外に「」システムを十分に信頼することはめったにでき ない... 2011/3/31 オブジェクト指向プログラミング入門 8 33
  • 34. 本番稼動時にどの表明レベルを選ぶ か?  ソフトウェアシステムというのは,操作を開始する 前に,信頼できるように作られなければならない.  もしあなたがプロジェクト管理者ならば,製品版の チェックが有効であることを決して開発者に前提と させてはならない.  開発中には,表明チェックが少なくとも事前条件レ ベルで必ず有効になっていることを確かめる.検査 を all に設定して,拡張テストを実行する.開発中 にバグが見つかった場合も all にする.  標準製品版に対しては,チェックなし版かチェック 付き版にするかは,あなたの査定に基づいて決める  もし,チェックなしでいこうと決めた場合でも,少 なくとも事前条件付き版をデリバリに加える. 2011/3/31 オブジェクト指向プログラミング入門 8 34
  • 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. 次回予定  日時: 2011年4月7日(木)13:0 0~14:30  場所: LB 2F/A 会議室  内容:例外処理 2011/3/31 オブジェクト指向プログラミング入門 8 36