ソフトウェアフレームワーク

**ソフトウェアフレームワーク**（）とは、プログラミングにおいて、アプリケーションソフトウェア等の実装に必要となる一般的な機能や定型コードを、ライブラリとしてあらかじめ用意したものである。例えば、Javaなどのオブジェクト指向言語向けのクラスライブラリとして実装されている場合は、再利用可能なソフトウェア部品（ソフトウェアコンポーネント）として用意されているクラスのインスタンスを自由に組み合わせたり、基本的な機能を持つ基底クラスを継承した派生クラスをユーザープログラマーが定義し、仮想メソッドによって公開されているカスタマイズポイントを選択的に上書きしたり特化させたりする。言語によってはコールバック関数やデリゲートを利用するなど、他にもさまざまな形態がある。文脈から明確な場合は単に「フレームワーク」としたり、特にアプリケーションソフトウェア開発向けであることを明確にした「アプリケーションフレームワーク」など、前後に別の語をつなげた複合語を使ったりすることもある。

ソフトウェアフレームワークは、明確に定義されたAPIを持ち、具体的な実装を再利用可能な形で隠蔽しているという点でライブラリとよく似ている。両者の間に明確な境界は無いし、分類のための明確な基準も無い。観点のひとつとしては、いわゆる「メインループ」あるいは「イベントループ」をアプリケーション側が持つか否か、という分類がある。メインループをアプリケーション側が持っていてそこから呼び出される形態のものがライブラリであり、一方フレームワークではメインループはフレームワーク側にあり、アプリケーションはそちら側から呼ばれるイベントハンドラによって駆動される（これについて「制御の反転」という語で説明されることがある）。

しかしこの分類は、両者を特徴づけるはっきりした分類というわけではない。アプリケーションの`main`関数はランタイムライブラリ中のスタートアップルーチンから呼び出される。また、広く使われているようなフレームワークでは、たいていはメインループをアプリケーション側が持つことができるようなメカニズムが用意されている。

ソフトウェアフレームワークは、最終的にアプリケーションソフトウェアにリンクされるライブラリコードだけでなく、開発に必要となる各種プログラミングツールも含んでいることがある。また、統合開発環境 (IDE) に組み込まれたプロジェクトテンプレートやソースコードジェネレータを活用した自動プログラミングの仕組みが用意されていることもある。

## 背景と批判
ソフトウェアフレームワークは、システム構築に必須な標準的かつ下位レベルの詳細を設計者やプログラマが検討する時間を省き、上位レベルの要求仕様（ビジネスロジック）の実現に多くの時間を割けるようにし、ソフトウェア開発を容易にすることを目指している。例えば、銀行のWebサイト構築にWebアプリケーションフレームワークを使っている開発チームは、要求処理や状態管理の機構を検討する時間を削減して、口座からの引き落としといった操作に注力できる。また、このような差分プログラミングの用途に適しているという理由で、フレームワークの実装にオブジェクト指向言語が選ばれることが多い。

批判としては、フレームワークは全体的なコードを肥大化させるという主張もある。これは複数のフレームワークで重複・競合する部分や補い合う部分があり、APIも複雑に絡み合っているためでもある。

フレームワークの使い方を学ぶ時間がかかるという主張もある。ただし一度フレームワークの使い方を学べば、同じフレームワークを利用する次のプロジェクトからはより素早く確実な応用が可能となる。また、多くのフレームワークは基本的な設計が似通っていることが多く、類推（アナロジー）により別のフレームワークにも考え方が応用できることが多い。

フレームワークは他のプラットフォーム製品（OS、DBMSなど）と同様に、特定のフレームワーク・ベンダーや、特定のバージョンに依存（ロックイン）されるリスクがあるとの主張もある。このため機能内容や代替製品などの確認も必要である。フレームワークのバージョンアップによって動作仕様が変わったり、API/ABIの互換性がなくなってしまったりすることもある。

移植の手間を減らして様々なOSに展開しやすくするための、クロスプラットフォームなフレームワークの開発も盛んである。特にGUIアプリケーションは通例OS固有のウィンドウシステムを利用する必要があり、またウィンドウの表示や2D/3Dグラフィックスの表示に必要となる準備（初期化や後始末）に手間がかかり、定型コードの量も多くなるため、詳細を隠蔽して抽象化したクロスプラットフォームなフレームワークが威力を発揮する。

フレームワークのソースコードが公開されていないプロプライエタリな製品では、不具合が見つかったときに原因の特定と解消が遅れるリスクもある。一方、オープンソースのフレームワークや内製フレームワークであっても、ユーザー数や実績が少なく未成熟な場合は、相対的に多数のバグが残されている可能性が高い。

いずれにしても、適切なフレームワークの選定は特に重要である。開発途中で、選択したフレームワークが開発要件を満たさないと判明した場合や、そのフレームワークの開発・提供が打ち切られた場合などは、開発途中で別のフレームワークに移行して（場合によっては基本設計から）再開発する必要が発生するためである。

## 例
ユーザーアプリケーションを立ち上げるのを助けるため、ソフトウェアフレームワークには一般にかなりの雑多なコードやユーティリティコードが含まれているが、全体としては特定の問題領域に注目した機能を提供している。以下に例を挙げる。
* 絵の描画、音楽作成、機械CAD
* 様々なプログラミング言語とターゲットマシン向けのコンパイラ
* 金融モデリングアプリケーション
* 地球システムモデリングアプリケーション
* 意思決定支援システム
* マルチメディアフレームワーク（メディアの再生と制作）
* Webアプリケーションフレームワーク
* ミドルウェア

## アーキテクチャ
Preeによれば、ソフトウェアフレームワークには「凍った部分 (frozen spot)」と「熱い部分 (hot spot)」がある。「凍った部分」はソフトウェアシステム全体のアーキテクチャ（基本コンポーネント群とそれらの相互関係）を定義する。それらはそのフレームワークを使って何を実装した場合でも常に変化しない。一方、「熱い部分」はプログラマがプロジェクト固有の機能に対応したコードを追加できる部分である。

ソフトウェアフレームワークには、ソフトウェアアーキテクチャ内でアプリケーションプログラマが特定の機能に対応したコードを置ける場所（すなわち「熱い部分」）が定義してある。

オブジェクト指向言語で、かつそれがクラスベースで具象クラスと抽象クラスがある場合には、前述の「凍った部分」を具象クラスで実装し、「熱い部分」のAPIを抽象クラスで宣言する、というスタイルでフレームワークを作る、という定型的手法がある。利用者（開発者）は、「熱い部分」の抽象クラスを継承した具象クラスを作り、メソッドなどに必要な機能を作り込む。

冒頭部で言及した制御の反転について、「ハリウッドの原則」と言われることがある（詳細は制御の反転#ハリウッドの原則を参照）。つまり「制御の反転」を前提として設計されているフレームワークを使う場合、開発者が書くコードが必要な時にフレームワークのコードを呼ぶスタイルではなく、フレームワークのコードから、ユーザーのインタラクション（マウスクリックや画面タップなど）によって発生するイベントなどに応じて開発者が書くコードが呼ばれるというスタイルになる、ということを、（買い手市場の）ハリウッドでは、仕事が得られる見込みがあるのならば電話が掛かってくるし、自分から電話を掛けても見込みは薄い、と例えたジョークである。

## 汎用フレームワークの一覧
* BFC (en) - .NET環境におけるデータベース中心型分散コンピューティングアプリケーション開発のためのRADフレームワーク
* CNI (Compiled Native Interface) - JavaコードとC++で書かれたアプリケーションやライブラリで相互に呼び出せるようにするGNU GCJ コンパイラ用のソフトウェアフレームワーク
* Component-based Scalable Logical Architecture (en) (CSLA) - .NETでビジネスオブジェクトを使った堅牢なオブジェクト指向プログラムを作成する標準的方法
* Habanero.NET (en) (Habanero) - .NETでドメイン駆動設計の原則を用いてエンタープライズアプリケーションを作成するためのオープンソースのフレームワーク
* Java Native Interface (JNI) - Java仮想マシン (VM) 上で動作しているJavaコードとVM外で動作するネイティブアプリケーション（そのハードウェアやOS上で直接動作するプログラム）や他の言語（C言語、C++、アセンブリ言語など）で書かれたライブラリの相互呼び出しを可能にする。
* Leonardi (en) - GUIアプリケーション向けのオープンソースのアプリケーションフレームワーク
* ActionScript Foundry (en) - ActionScript 3 とJavaで書かれたオープンソースのFlexフレームワーク
* Spring - Javaプラットフォーム向けのオープンソースのアプリケーションフレームワーク
* JSF - Javaプラットフォーム向けのオープンソースのWebアプリケーションフレームワーク。コンポーネントベースのイベント駆動型アプローチによる素早い開発。
* Symfony - PHPプラットフォーム向けのオープンソースのアプリケーションフレームワーク
* CodeIgniter - PHPプラットフォーム向けのオープンソースのアプリケーションフレームワーク
* Rails - Rubyプラットフォーム向けの自由ソフトウェアのアプリケーションフレームワーク
* Zend Framework - PHPプラットフォームと緩やかに結合したコンポーネントライブラリを持つ、強力で拡張性のあるアプリケーションフレームワーク
* Twisted - インターネットアプリケーション用にPythonで書かれたオープンソースのイベント駆動型アプリケーションフレームワーク
* Google Web Toolkit (GWT) - オープンソースのJavaソフトウェア開発フレームワーク
* liferay - オープンソースのWebアプリケーションシステム用のポートレットフレームワーク

## 関連項目
* アプリケーションフレームワーク
* クラス (コンピュータ)
* デザインパターン (ソフトウェア)
* Don't repeat yourself
* Jini | Upnp 
* プログラミングパラダイム
* Webアプリケーションフレームワーク

## 脚注・出典

## 外部リンク
* Annual frameworks conference
* Frameworks vs. Libraries DDJ、2006年7月7日
* What is framework?
* A Quest to Define a Framework