オブジェクト指向
プログラミング入門
ソフトウェア基礎講座 第3回
2011年2月21日
服部健太
2011/2/21
再利用の利点
 適時性
 開発するソフトウェアの数が減れば,より迅速にソフトウェア
を構築できる
 保守作業の軽減
 再利用する部品の保守はその開発者に任せられる
 信頼性
 評判の良い部品ならばバグは少ないだろうと期待できる
 効率性
 その部品は専門家が開発したのだから最善の解決方法で実現さ
れているだろうと期待できる
 一貫性
 良いライブラリを使えば,そのライブラリのスタイルが開発中
のソフトウェアに踏襲される
 投資
 優秀な開発者のノウハウと発明を保存できる
消費者にとっ
ての利点
生産者にとっ
ての利点
2オブジェクト指向プログラミング入門 3
2011/2/21
再利用部品の生産者になるには?
 いきなり再利用部品の生産者になるのは無理
 再利用可能な部品は一日にしてならず
 鍛錬の賜物である
 まず,再利用部品の利用者になれ
 既存の良い部品を使う
 それについて学習する
 模倣する
3オブジェクト指向プログラミング入門 3
2011/2/21
何を再利用すべきか?
 人材の再利用
 ソフトウェア業界に広く行なわれてるが効果は限定的
 設計と仕様の再利用
 ソフトウェアの進化にドキュメントが追いつかない
 デザインパターン
 すぐれたパターンはソフトウェア部品であるべき
 ソースコードの再利用
 情報隠蔽が失われる,モジュール性規約の可能性
 抽象化されたモジュールの再利用
 再利用可能な基本要素はソフトウェア要素でなければなら
ない
4オブジェクト指向プログラミング入門 3
2011/2/21
ソフトウェア開発における繰返し
 ソフトウェア開発には同じことの繰返しが多
い
 ソート,検索,読み出し,書き出し,比較,走査
,割り付け,同期調整,・・・
あなた自身,あるいは,あなたの部下は過去 6 ヶ
月の間に表検索のプログラムを何回書きましたか?
5オブジェクト指向プログラミング入門 3
2011/2/21
「非」技術的障害
 NIH ( Not Invented Here )症候群
 実際には広く知られた簡単に入手できる再利用可
能な良い手段があれば再利用される
 単に開発者が新しい未知の部品に対して用心深く
なっているだけ
 ⇒ 再利用可能な部品は品質がより重要
 調達の経済学
 顧客は再利用部品を開発するためのコストを負担
してはくれない
6オブジェクト指向プログラミング入門 3
2011/2/21
「非」技術的障害(2)
 ソフトウェア会社とその戦略
 再利用可能なソフトウェアを顧客に提供したら,
顧客は次の仕事を発注する必要が無くなる!?
 再利用可能な部品の構築が可能ならば,遅かれ早
かれ誰かが作る
 再利用の目的は人をツールで置き換えることでは
なく,人に任せる部分とツールに任せる部分の割
合を変更すること
 ⇒ 部品のビジネスがサービスのビジネスの土台になる
7オブジェクト指向プログラミング入門 3
2011/2/21
「非」技術的障害(3)
 部品を入手する
 部品を管理する仕事は困難である
 部品の適切なデータベースの開発が必要
 Perl の CPAN とか Ruby Gems とか...
 部品のインデックス付け
 個々の部品に対してインデックス情報を付加できるような
メカニズム
 再利用可能な部品の配布形式
 ソース形式かショート形式(インタフェース記述+バイナ
リ)か
 継承による再利用の場合,ショート形式では不十分
 再利用部品の評価
8オブジェクト指向プログラミング入門 3
2011/2/21
技術的な問題
 変更と不変性
 プログラマは同じようなことを何度も繰返す傾向
があるが,全く同じことをしているわけではない
 表検索の例:
 配列
 リスト
 逐次ファイル
 二分木
 Bツリー
 ハッシュ
 ・・・
has (t: TABLE, x: ELEMENT): BOOLEAN is
-- 要素 x は表 t の中にあるか ?
local
pos: POSITION
do
from
pos := INITIAL_POSITION(x, t)
until
EXHAUSTED(pos, t) or else FOUND(pos, x, t)
loop
pos := NEXT(pos, x, t)
end
Result := not EXHAUSTED(pos, t)
end
ルーチンのパター
ン:
大文字で書かれてい
る要素は実装によっ
て異なってくる部分
9オブジェクト指向プログラミング入門 3
2011/2/21
技術的な問題(2)
 再利用とやり直しのジレンマ
 どうすれば多くのバリエーションの必要性を保ちながら,
共通のパターンを利用できるか?
 ソフトウェアの多様性ゆえに再利用可能なモジュールには
柔軟性が必要となる
 モジュールを凍結してしまうと,再利用かやり直しのジレ
ンマが生じる
 全くそのままモジュールを利用するか,完全にやり直すか
 よくあるケース:
 そのモジュールが今の仕事の部分的な解決策にはなるが,完
全な解決策とはいかない
 ⇒  そのモジュールの振る舞いをいくらか調整する必要があ
る
 ⇒  開放/閉鎖の原則
10オブジェクト指向プログラミング入門 3
2011/2/21
モジュール構造の5つの要件
 適応の可能性を維持しながらそのまま再利用できる
部品を生み出すモジュール構造はどうしたら見つけ
ることができるか?
 型のバリエーション( Type Variation )
 ルーチンのグループ分け( Routine Grouping )
 実装のバリエーション( Implementation
Variation )
 表現の独立性( Representation Independence )
 共通の振る舞いのふるい出し( Factoring Out
Common Behaviors )
11オブジェクト指向プログラミング入門 3
2011/2/21
型のバリエーション
 ルーチンパターン has の例:
 ELEMENT 型のオブジェクトを保持する表
 詳細化するには, INTEGER や
BANK_ACCOUNT などの具体的な型を使って,
このパターンを整数や銀行口座の表に適用する
 再利用可能な検索モジュールは,再利用する
人がソフトウェアを書き換えなくても,多く
の型の要素に適用できなければならない
 パラメータとして型を渡すことのできるモジュー
ル
 ⇒ 総称( generic )モジュールのための機能が必
要 12オブジェクト指向プログラミング入門 3
2011/2/21
ルーチンのグループ分け
 型をパラメータ化しただけでは不十分
 has ルーチンパターンの例:
 表をどのように検索するかは,表がどのように作
られたか,表の要素がどのように挿入されるか,
削除されるかによって異なる
 ⇒ 再利用可能なモジュールには,作成,挿入,削
除,検索といったそれぞれの操作のためのルーチ
ンからなるルーチン群が含まれて居なければなら
ない
 「パッケージ」と呼ばれる形式のモジュール
13オブジェクト指向プログラミング入門 3
2011/2/21
実装のバリエーション
 has パターンは一般的なので実際には,適用
されるデータ構造やアルゴリズムにはさまざ
まな種類がある
 一つのモジュールですべての可能性に対処するこ
とは無理(巨大なモジュールになってしまう)
 異なる実装のすべてを網羅するモジュールの
ファミリーが必要
14オブジェクト指向プログラミング入門 3
2011/2/21
表現の独立性
 汎用的な形式の再利用可能なモジュールでは,顧客
はどのように実装されているかを知らずに操作を指
定できなければならない
 has の例:
 顧客モジュール C が呼び出しをするときに表 t がどのよう
な表であるかを知らずに次ぎのような呼び出しによって要
素があるかないかの情報が得られる
 present := has(t, x)
 C を書く人が知っていなければならないことは, t が何ら
かの型の要素からなる表であることと, x がその型のオブ
ジェクトを表すことだけ
 情報隠蔽の原則の拡張
 t の実行時の形式にあわせて自動的に has が調整されるよ
うにしたい⇒動的束縛( dynamic binding )
15オブジェクト指向プログラミング入門 3
2011/2/21
共通する振る舞いのふるい出し
 表検索の例
 何らかのハッシュ法によって管理されている表
 何らかのツリーとして構成されている表
 逐次的に管理されている表(逐次表)
 配列,連結リスト,ファイル
16オブジェクト指向プログラミング入門 3
2011/2/21
例:逐次表のための検索ルーチン
has (t: SEQUENTIAL_TABLE, x: ELEMENT): BOOLEAN is
-- 要素 x は表 t の中にあるか ?
do
from start until
after or else found(x)
loop
forth
end
Result := not after
end
start forth after found(x)
配列 i := 1 i := i+1 i > count t@i = x
連結リス
ト
c := first_cell c := c.right c = Void c.Item = x
ファイル rewind read end_of_file f^↑ = x
17オブジェクト指向プログラミング入門 3
2011/2/21
伝統的なモジュール構造:ルーチ
ン
 特に数値計算の分野では成功しており,いくつかの優れたライ
ブラリがある
 ルーチンが上手くいく場合
 個々の問題の全ての場合を数少ない入出力引数によって表現可
能
 問題と問題がはっきり分かれている
 複雑なデータ構造が含まれていない
 ルーチンの限界(表検索を例に)
 一つの検索ルーチンで多くのケースに対処しようとすると,長
い引数リストが必要になり,内部構造も複雑になる
 それぞれが特定のケースに対処する多数の検索ルーチンを作成
すると,個々のルーチンがほかのルーチンと詳細な部分が少し
だけ異なるルーチンができる
 ルーチンには柔軟性がない
 修正するための唯一の方法は異なる引数を渡すこと
18オブジェクト指向プログラミング入門 3
2011/2/21
伝統的なモジュール構造:パッケー
ジ
 パッケージは次ぎのような属性を備える
 言語の構成要素の一つ.すべてのパッケージには
名前と明確な構文範囲がある
 個々のパッケージの定義には,ルーチンや変数な
どの関連する要素(パッケージの特性)の宣言が
複数含まれている
 すべてのパッケージにおいてほかのパッケージに
おける特性の使用を管理する厳密なアクセス権を
指定できる(情報隠蔽のサポート)
 コンパイル可能な言語では,パッケージを個別に
コンパイルできる
19オブジェクト指向プログラミング入門 3
2011/2/21
整数の表の二分木による実装例
package INTEGER_TABLE_HANDLING feature
type INTBINTREE is
record
-- 二分木表現の記述の一例:
info: INTEGER
left, right: INTBINTREE
end
new: INTBINTREE is
-- 適切に初期化された新しい INTBINTREE を返す
do … end
has(t: INTBINTREE; x: INTEGER): BOOLEAN is
-- t の中に x があるか?
do … …検索操作の実装 end
put(t: INTBINTREE, x: INTEGER) is
-- t に x を挿入する
do …end
remove( …
end -- パッケージ INTEGER_TABLE_HANDLING
20オブジェクト指向プログラミング入門 3
2011/2/21
典型的な利用者側の例
-- 補助的な宣言
x: INTEGER; b: BOOLEAN
-- INTEGER_TABLE_HANDLING で定義されている型で t
を
-- 宣言する
t: INTEGER_TABLE_HANDLING$INTBINTREE
-- ファンクション new によって作成される新しいテーブル
として
-- t を初期化する:
t := INTEGER_TABLE_HANDLING$new
-- プロシージャ put を使って x の値を表に挿入する:
INTEGER_TABLE_HANDLING$put(t, x)
-- x が t の中にあるかどうかによって True または False を b
に代入 -- する
-- 検索にはファンクション has を使う
b := INTEGER_TABLE_HANDLING$has(t, x)
21オブジェクト指向プログラミング入門 3
2011/2/21
パッケージの限界
 モジュールとデータ型の2つの名前を作る必
要がある
 型のバリエーションに対応していない
 パッケージを総称的にすることで解決可能
 多くのカプセル化支援言語では,インタ
フェースと実装の 2 つの部分に分けてパッ
ケージを宣言する
 ⇒ ヘッダ宣言をコピーするという余分な作業が発
生
22オブジェクト指向プログラミング入門 3
2011/2/21
パッケージの評価
 ルーチンよりは優れている
 供給者モジュールの作者は,ある与えられた概念に関係す
るソフトウェア要素をすべて一箇所にまとめてコンパイル
できる
 ⇒ デバッグと変更が楽になる
 顧客モジュールの作者にとっては,関連する機能群がすべ
て一箇所にあれば探しやすく使いやすい.
 完全に満足はできない
 共通性のふるい出しの要件を満たしていない
 多くの異なる実装のためのモジュールを提供する必要がある
 独立性の要件を満たしていない
 顧客が表を使用するたびに次ぎのような宣言が必要:
 t: INTEGER_TABLE_HANDLING$INTBINTREE
23オブジェクト指向プログラミング入門 3
2011/2/21
多重定義と総称性
 多重定義と総称性という2つの技法は,前述
のさまざまなメカニズムの柔軟性を高める方
法である
24オブジェクト指向プログラミング入門 3
2011/2/21
構文的多重定義
 多重定義はプログラム中の名前に 1 つ以上の意味を
付加する機能である.
 変数名の多重定義
 ほとんどすべての言語で可能
 異なるモジュールに属する変数であれば,異なる変数が同
じ名前を持てる
 ルーチン(演算子)の多重定義
 算術演算子など: a+b という表記が a と b の型によってさ
まざまな形式の加算を意味する
 シグネチャが異なればパッケージ中に複数の同じ名前の
ルーチンを許す言語もある
25オブジェクト指向プログラミング入門 3
2011/2/21
多重定義の役割
 供給者側
square(x:INTEGER):INTEGER is do … end
square(x:REAL):REAL is do … end
square(x:DOUBLE):DOUBLE is do … end
square(x:COMPLEX):COMPLEX is do … end
 顧客側
 変数 x の型によらず, square(x) と書くだけでよい
ルーチンの多重定義は顧客のための機能である.あ
る一つの概念を表す異なる実装を使うとき,顧客は
一つの記述で済ませることができる.
26オブジェクト指向プログラミング入門 3
2011/2/21
構文的多重定義の限界
 表現の独立性は満たされない
 has(t, x)
 t は宣言しなくてはならず,顧客は t がどのような
表であるかを厳密に知っている必要がある.
 シグネチャが同じケースの場合
 p1 := new_point(n, v)
 デカルト座標を使う方法も極座標を使う方法も同
じシグネチャを使う
 new_point(p,q:REAL):POINT
27オブジェクト指向プログラミング入門 3
2011/2/21
意味的多重定義
 動的束縛は意味的多重定義と呼ぶことができ
る
 表現の独立性を満たす
 has(t, x)
 t がどのような表かは知らずともよい
 「公明正大の原則」に違反する
<公明正大の原則>
意味の違いがソフトウェアテキストの違いに反映さ
れるべきである.
28オブジェクト指向プログラミング入門 3
2011/2/21
総称性
 「型のバリエーション」問題の直接的な答え
 次のような複数のモジュールを書く必要をな
くし
 INTEGER_TABLE_HANDLING
 ELECTRON_TABLE_HANDLING
 ACCOUNT_TABLE_HANDLING
 次のような形式のモジュールパターンを一つ
だけ書けば済む
 TABLE_HANDLING[G]
 G は仮総称パラメータ
29オブジェクト指向プログラミング入門 3
2011/2/21
総称性の役割
総称性は供給者モジュールの作者のための機能であ
る.ある特定の概念を表す 1 つの実装を異なるオ
ブジェクトに適用するとき,同じ供給者モジュール
テキストを書くことが可能になる
30オブジェクト指向プログラミング入門 3
モジュール技法の評価
 パッケージと総称性によって解決できたこと
 ルーチンのグループ分け
 型のバリエーション
 未解決の問題
 実装のバリエーション
 表現の独立性
 共通する振る舞いのふるい出し
2011/2/21 31オブジェクト指向プログラミング入門 3
次回予定
 日時:2011年2月28日(月)10:3
0~
 場所: LB  2 F / A 会議室
 内容:オブジェクト技術への道
2011/2/21 オブジェクト指向プログラミング入門 3 32

オブジェクト指向入門3