抽象化_(計算機科学)
[Wikipedia|▼Menu]
例えば、港湾事務所での船員への給与支払い業務システムを考えてみよう。

最も高いレベルには、典型的なエンドユーザー操作のメニューがある。

その下に、船員の新規採用や退職、小切手の印刷といった作業のための独立した実行ファイルライブラリがある。

各独立コンポーネントは多数のソースファイルから構成され、それぞれのファイルには問題の一部に対応するプログラムコードが含まれ、他のプログラムとある決まったインタフェースを持つよう設計される。新規採用プログラムには、データを画面表示するプログラムやデータベースとのインタフェースが含まれるだろう(それらは独立したサードパーティーライブラリや静的にリンクされたライブラリルーチン群かもしれない)。

また、港湾と船の間でデータを交換する処理が必要とされる場合も考えられ、その場合はさらに様々なコンポーネントを必要とする。

このような階層によってコンポーネント毎に実装の詳細を隔離する効果が生まれる。そして、その考え方を重視し、拡張して生まれたのがオブジェクト指向プログラミングである。
データ抽象化[ソースを編集]詳細は「抽象データ型」を参照

データ抽象化とは、データ型の「抽象的」属性と「具体的」実装詳細の明確な分離を強制することである。抽象化された属性はデータ型(あるいはそのインタフェース)を利用するクライアントコードとして明確化され、具体的実装は完全にプライベートな状態でかつ必要に応じて変更できる形で存在する。概念的には、そのような変更は抽象的振る舞いには変化をもたらさないので、クライアントコードには全く影響を与えない。

例えば、「参照テーブル」という抽象データ型を定義したとする。参照テーブルには「キー」とユニークに対応する「値」があり、キーを指定することで値を操作できる。このような参照テーブルの実装方法はハッシュテーブル2分探索木線形リストなどいくつかある。クライアントコードからすれば、データ型の抽象化された属性はどの場合でも同じである。

もちろん、以上の話は最初にインタフェースを正しく詳細化することにかかっており、そうでないと実装の変更がクライアントコードに影響を及ぼしてしまう。別の見方をすれば、インタフェースをデータ型とクライアントコードの間で合意された振る舞いの「契約」を形成すると考えることもできる。契約にない部分は予告なく変更される可能性がある、というわけである。

データ抽象化を実装した言語としてはAdaModula-2がある。オブジェクト指向プログラミング言語も一般にデータ抽象化を提供すると言われているが、継承の概念によって実装側の情報がインタフェース側に持ち出される傾向がある。したがって、継承関係の変更はクライアントコードに影響を与えることがあり、脆弱な基底クラス問題につながる。
オブジェクト指向プログラミングでの抽象化[ソースを編集]詳細は「オブジェクト指向プログラミング」を参照

オブジェクト指向プログラミングの理論では、抽象化とは抽象的「アクター」であるオブジェクトを定義する機能であり、アクターは作業を行い、状態を変化させ、状態を報告し、システム内の他のオブジェクトと「通信」する。カプセル化は、状態の詳細を隠蔽することを意味する用語だが、従来のプログラミング言語でのデータ型の概念の拡張である。カプセル化はデータに強く結びついた「振る舞い」をそのデータと関連付け、他のデータ型との相互作用を標準化し、抽象化の起点となる。抽象化をさらに進めて、異なる型のオブジェクト間で同じ操作を定義することをポリモーフィズムと呼ぶ。また、逆方向に抽象化を進め、データ型やクラスの内部を抽象化してそれらの複雑な関係を単純化し構造化することを委譲または継承と呼ぶ。

オブジェクト指向言語は様々あるが、似たような抽象化手法を提供している。ポリモーフィズムはほぼ全てのオブジェクト指向言語でサポートされており、類似あるいは同じ役割を持つデータ型の置換なども含まれる。それほど一般的ではないが、構成・イメージ・パッケージによってコンパイル時/リンク時/ロード時にオブジェクト間の関係を決定することがあり、この場合実行時に関係を決定する必要性がほとんどなくなる。

Selfなどの言語では、クラスとインスタンスをあまり区別せず、ポリモーフィズムの実現に委譲をよく使う。

C++では、テンプレート演算子オーバーロード、その他のコンパイル時の静的バインディングなどが特徴であり、これらがC++固有の柔軟性に関する問題を生んでいる。

同じ抽象化にも様々な戦略があるが、基本的に抽象名詞をコード内でサポートする必要性に違いはない。いずれのプログラミング言語も動詞を関数として、名詞をデータ構造として、そして両者を合わせてプロセスとして抽象化する機能に基づいている。

例えば、以下のサンプルコードはJavaによる動物の抽象的表現である。ここでは、飢えと食事という観点で抽象化している。Animalクラスは動物の状態と機能を表現するよう定義されている。class Animal extends LivingThing { Location loc; double energyReserves; boolean isHungry() { if (energyReserves < 2.5) { return true; } else { return false; } } void eat(Food f) { // Consume food energyReserves += f.getCalories(); } void moveTo(Location l) { // Move to new location loc = l; }}

この定義で、Animal型のオブジェクトを生成し、以下のようにメソッドを呼び出すことができる:thePig = new Animal();theCow = new Animal();if (thePig.isHungry()) { thePig.eat(tableScraps); }if (theCow.isHungry()) { theCow.eat(grass); }theCow.moveTo(theBarn);

この例では、Animalクラスが動物を抽象化したもので、LivingThing は Animal よりさらに高い抽象度の抽象化(この場合汎化)である。

もっと違った抽象化も考えられる。例えば中間的な抽象化として、毎日ミルクを生み出してくれる動物と、最後に肉となってくれるだけの動物とに分類することができる。DailyAnimal (雌牛や山羊)はミルクを生み出すのに適した餌を与えられ、Animal (豚や雄牛)は肉の質を高める餌を与えられる。

このような抽象化をすれば、アプリケーションを書く人は餌の種類を指定する必要がなくなり、給餌スケジュールに集中することができるようになる。この2つのクラスは継承関係であっても、全く独立していてもよく、それによってポリモーフィズムの度合いも変わってくる。このような機能は言語によって大きく違うが、大体においてある言語でできることは他の言語でも可能である。演算子オーバーロードや抽象データ型を多用することで、継承や他のポリモーフィズムを実現する手法と同様の効果が得られる。クラスを使った記法は単にコードを書くものの利便性のために存在するに過ぎない。
オブジェクト指向設計[ソースを編集]詳細は「オブジェクト指向」を参照

何を抽象化して、何をコードを書く者の制御下に置くかの判断は、オブジェクト指向設計とドメイン分析の主要テーマである。実世界での適切な関係を見極めることは、オブジェクト指向分析のテーマでもある。

一般に、適切な抽象化を決定するには、範囲/ドメイン分析/連携すべきシステムの決定/様々な制約の分析など、様々な判断を必要とする。


次ページ
記事の検索
おまかせリスト
▼オプションを表示
ブックマーク登録
mixiチェック!
Twitterに投稿
オプション/リンク一覧
話題のニュース
列車運行情報
暇つぶしWikipedia

Size:31 KB
出典: フリー百科事典『ウィキペディア(Wikipedia)
担当:undef