フレームワーク入門 - ライブラリとの違いを理解する
このドキュメントの目的
フレームワーク(Framework) の本質を理解し、ライブラリとの根本的な違いを明確にすることが目標です。
目次
フレームワークとは
定義
フレームワークは、アプリケーションの「骨組み」や「枠組み」を提供するソフトウェアです。
┌─────────────────────────────────────────────────────────────┐
│ フレームワークのイメージ │
├─────────────────────────────────────────────────────────────┤
│ │
│ フレームワーク = 家の骨組み(柱・梁・基礎) │
│ │
│ ┌─────────────────────────────────────────────┐ │
│ │ ┌──┐ ┌──┐ ┌──┐ │ │
│ │ │ │ │ │ │ │ ← 柱 │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ ├──────┤ ├──────┤ │ ← 梁 │ │
│ │ │ │ │ │ │ │ │ │
│ │ │ │ 壁や │ │ 家具 │ │ │ │
│ │ │ │ 内装 │ │ など │ │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ └──┴──────┴──┴──────┴──┘ ← 基礎 │ │
│ └─────────────────────────────────────────────┘ │
│ │
│ あなたが作るのは「壁」「内装」「家具」の部分 │
│ 骨組みはフレームワークが提供 │
│ │
└─────────────────────────────────────────────────────────────┘
具体例
┌─────────────────────────────────────────────────────────────┐
│ Webアプリの場合 │
├─────────────────────────────────────────────────────────────┤
│ │
│ フレームワークが提供するもの: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ ・HTTPリクエストの受け取り │ │
│ │ ・URLとコードのマッピング(ルーティング) │ │
│ │ ・リクエスト/レスポンスの変換 │ │
│ │ ・データベース接続管理 │ │
│ │ ・セッション管理 │ │
│ │ ・セキュリティ(認証・認可) │ │
│ │ ・ログ出力 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ あなたが作るもの: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ ・ビジネスロジック(業務処理) │ │
│ │ ・画面表示(テンプレート) │ │
│ │ ・データの検証ルール │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
ライブラリとの違い
最大の違い: 誰がコードを呼び出すか
┌─────────────────────────────────────────────────────────────┐
│ ライブラリ vs フレームワーク │
├─────────────────────────────────────────────────────────────┤
│ │
│ 【ライブラリ】 │
│ あなたのコードがライブラリを呼び出す │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ あなたのコード │ ────→ │ ライブラリ │ │
│ │ │ │ │ │
│ │ main() { │ │ sort() │ │
│ │ sort(...)│─呼出→│ format() │ │
│ │ } │ │ parse() │ │
│ └──────────────┘ └──────────────┘ │
│ │
│ 「あなた」が主導権を持っている │
│ │
├─────────────────────────────────────────────────────────────┤
│ │
│ 【フレームワーク】 │
│ フレームワークがあなたのコードを呼び出す │
│ │
│ ┌──────────────────────────────────────────┐ │
│ │ フレームワーク │ │
│ │ ┌────────────────────────────────────┐ │ │
│ │ │ main() ← フレームワークが持つ │ │ │
│ │ │ ↓ │ │ │
│ │ │ リクエスト受信 │ │ │
│ │ │ ↓ │ │ │
│ │ │ ルーティング │ │ │
│ │ │ ↓ │ │ │
│ │ │ ┌──────────────────┐ │ │ │
│ │ │ │ あなたのコード │ ←呼出 │ │ │
│ │ │ │ (Controller等) │ │ │ │
│ │ │ └──────────────────┘ │ │ │
│ │ │ ↓ │ │ │
│ │ │ レスポンス送信 │ │ │
│ │ └────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────┘ │
│ │
│ 「フレームワーク」が主導権を持っている │
│ │
└─────────────────────────────────────────────────────────────┘
比較表
| 観点 | ライブラリ | フレームワーク |
|---|---|---|
| 主導権 | あなたのコード | フレームワーク |
| 呼び出し方向 | あなた → ライブラリ | フレームワーク → あなた |
| main()の所在 | あなたのコード | フレームワーク |
| 使う範囲 | 必要な部分だけ | アプリ全体に影響 |
| 学習コスト | 低い(APIを覚える) | 高い(設計思想の理解) |
| 入れ替え | 容易 | 困難(書き直し) |
コードで見る違い
// ========================================
// ライブラリを使う場合
// ========================================
// あなたがmain()を書き、ライブラリを呼び出す
import com.google.gson.Gson; // JSONライブラリ
public class MyApp {
public static void main(String[] args) { // あなたが制御
// あなたがライブラリを呼び出す
Gson gson = new Gson();
String json = gson.toJson(user);
// 処理の流れはあなたが決める
System.out.println(json);
}
}
// ========================================
// フレームワークを使う場合
// ========================================
// main()はフレームワークが持つ
// あなたはフレームワークのルールに従ってコードを書く
@RestController // フレームワークが認識するマーカー
public class UserController {
// フレームワークがこのメソッドを呼び出す
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) {
return userService.findById(id);
}
// あなたはビジネスロジックだけ書く
// HTTPの処理、JSON変換はフレームワークが行う
}
制御の反転(IoC)
IoC = Inversion of Control
フレームワークとライブラリの違いを説明する重要な概念です。
┌─────────────────────────────────────────────────────────────┐
│ 制御の反転(IoC) │
├─────────────────────────────────────────────────────────────┤
│ │
│ 【通常の制御】 │
│ │
│ あなたのコード ────────→ 呼び出し ───→ 他のコード │
│ │ │
│ └── 制御の流れを決定 │
│ │
│ 「何を」「いつ」「どの順番で」実行するか、あなたが決める │
│ │
├─────────────────────────────────────────────────────────────┤
│ │
│ 【反転した制御】 │
│ │
│ フレームワーク ────────→ 呼び出し ───→ あなたのコード │
│ │ │
│ └── 制御の流れを決定 │
│ │
│ 「何を」「いつ」「どの順番で」はフレームワークが決める │
│ あなたは「呼ばれたときに何をするか」だけを書く │
│ │
└─────────────────────────────────────────────────────────────┘
日常の例え
┌─────────────────────────────────────────────────────────────┐
│ 日常での例え │
├─────────────────────────────────────────────────────────────┤
│ │
│ 【ライブラリ = 工具箱】 │
│ │
│ あなたが大工さん │
│ 工具箱から必要な工具を取り出して使う │
│ │
│ 「今はノコギリを使おう」 │
│ 「次はカナヅチだ」 │
│ → 使うタイミングと順番はあなたが決める │
│ │
├─────────────────────────────────────────────────────────────┤
│ │
│ 【フレームワーク = ファストフード店のマニュアル】 │
│ │
│ あなたは店員 │
│ マニュアル(フレームワーク)に従って働く │
│ │
│ 「注文が来たら→挨拶→注文を聞く→調理→提供」 │
│ → 流れはマニュアルが決めている │
│ → あなたは「調理」部分の中身だけを考える │
│ │
└─────────────────────────────────────────────────────────────┘
ハリウッドの原則
IoC は「ハリウッドの原則」とも呼ばれます。
┌─────────────────────────────────────────────────────────────┐
│ "Don't call us, we'll call you" │
│ (電話してくるな、こちらから電話する) │
├─────────────────────────────────────────────────────────────┤
│ │
│ 映画のオーディションで: │
│ │
│ 監督: 「結果はこちらから連絡します」 │
│ 役者: ひたすら待つ(自分からは電話しない) │
│ │
│ フレームワークで: │
│ │
│ フレームワーク: 「必要なときに呼び出します」 │
│ あなたのコード: 呼ばれるのを待つ │
│ │
│ @GetMapping("/users") │
│ public List<User> getUsers() { ... } │
│ ↑ │
│ このメソッドをいつ呼ぶかはフレームワークが決める │
│ あなたは「呼ばれたら何をするか」だけ書く │
│ │
└─────────────────────────────────────────────────────────────┘
フレームワークを使う理由
1. 車輪の再発明を防ぐ
┌─────────────────────────────────────────────────────────────┐
│ フレームワークなしで作ると... │
├─────────────────────────────────────────────────────────────┤
│ │
│ Webアプリを一から作る場合: │
│ │
│ □ HTTPサーバーの実装 │
│ □ リクエストのパース │
│ □ URLルーティングの仕組み │
│ □ セッション管理 │
│ □ SQLインジェクション対策 │
│ □ CSRF対策 │
│ □ XSS対策 │
│ □ 認証・認可の仕組み │
│ □ ログ出力の仕組み │
│ □ 設定ファイルの読み込み │
│ □ ... │
│ │
│ → 膨大な量のインフラコードが必要 │
│ → 本来作りたいもの(業務ロジック)に集中できない │
│ │
└─────────────────────────────────────────────────────────────┘
2. ベストプラクティスの適用
┌─────────────────────────────────────────────────────────────┐
│ フレームワークが提供するもの │
├─────────────────────────────────────────────────────────────┤
│ │
│ フレームワークには多くの開発者の知見が凝縮されている │
│ │
│ ✓ セキュリティ対策 │
│ → 何千人もの開発者がレビュー・テスト済み │
│ │
│ ✓ パフォーマンス最適化 │
│ → コネクションプーリング、キャッシュなど │
│ │
│ ✓ 設計パターン │
│ → 長年の経験から生まれた構造 │
│ │
│ ✓ エラーハンドリング │
│ → 適切な例外処理、ログ出力 │
│ │
└─────────────────────────────────────────────────────────────┘
3. チーム開発の効率化
┌───────────────────────────────────── ────────────────────────┐
│ チーム開発での利点 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 共通の「お作法」がある │
│ │
│ フレームワークなし: │
│ ┌─────────────────────────────────────────┐ │
│ │ Aさん: 「私はこの構造で作った」 │ │
│ │ Bさん: 「僕は全然違う構造だよ」 │ │
│ │ Cさん: 「え、どこに何があるの...?」 │ │
│ └─────────────────────────────────────────┘ │
│ → コードを読むのに時間がかかる │
│ → 引き継ぎが困難 │
│ │
│ フレームワークあり: │
│ ┌─────────────────────────────────────────┐ │
│ │ 全員: 「Controllerはここ、Serviceはここ」│ │
│ │ 「設定ファイルの場所も決まってる」 │ │
│ └─────────────────────────────────────────┘ │
│ → 構造が統一される │
│ → 新メンバーも理解しやすい │
│ │
└─────────────────────────────────────────────────────────────┘
4. エコシステムの活用
┌─────────────────────────────────────────────────────────────┐
│ エコシステムの恩恵 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 人気フレームワークには豊富なエコシステムがある │
│ │
│ Spring Framework の例: │
│ ├── Spring Security → 認証・認可 │
│ ├── Spring Data → データアクセス │
│ ├── Spring Cloud → マイクロサービス │
│ ├── Spring Batch → バッチ処理 │
│ └── Spring Session → セッション管理 │
│ │
│ その他: │
│ ├── 豊富なドキュメント │
│ ├── Stack Overflow での質問・回答 │
│ ├── チュートリアル、書籍 │
│ └── サードパーティライブラリとの連携 │
│ │
└─────────────────────────────────────────────────────────────┘
フレームワークの種類
Webフレームワーク
HTTPリクエストを処理するWebアプリケーションを構築するためのフレームワーク。
| 言語 | フレームワーク | 特徴 |
|---|---|---|
| Java | Spring Boot | エンタープライズ向け、DI/AOP |
| Java | Jakarta EE | Java標準、仕様ベース |
| Python | Django | フルスタック、管理画面付き |
| Python | Flask | 軽量、マイクロフレームワーク |
| JavaScript | Express.js | 軽量、Node.js向け |
| JavaScript | NestJS | TypeScript、Angular風 |
| Ruby | Ruby on Rails | CoC、高い生産性 |
| Go | Gin | 高速、軽量 |
| PHP | Laravel | モダン、充実した機能 |
フロントエンドフレームワーク
SPAやUIを構築するためのフレームワーク。
| フレームワーク | 特徴 |
|---|---|
| React | コンポーネント指向、仮想DOM |
| Vue.js | 学習しやす い、段階的採用可能 |
| Angular | フルスタック、TypeScript |
| Svelte | コンパイル時最適化 |
テストフレームワーク
テストコードを記述・実行するためのフレームワーク。
| 言語 | フレームワーク |
|---|---|
| Java | JUnit, TestNG |
| JavaScript | Jest, Mocha |
| Python | pytest, unittest |
フレームワークの選択基準
┌─────────────────────────────────────────────────────────────┐
│ フレームワーク選択の観点 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. プロジェクトの要件 │
│ ・規模は?(小規模〜大規模) │
│ ・パフォーマンス要件は? │
│ ・セキュリティ要件は? │
│ │
│ 2. チームのスキル │
│ ・チームが使い慣れている技術は? │
│ ・学習コストは許容できる? │
│ │
│ 3. エコシステム │
│ ・ドキュメントは充実している? │
│ ・コミュニティは活発? │
│ ・必要なライブラリは揃っている? │
│ │
│ 4. 将来性 │
│ ・メンテナンスは継続される? │
│ ・長期サポートはある? │
│ │
└─────────────────────────────────────────────────────────────┘
idp-server での実例
このプロジェクトでは Spring Boot を採用していますが、多くの機能を自作しています。
┌─────────────────────────────────────────────────────────────┐
│ idp-server の構成例 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Spring Boot が提供するもの: │
│ ├─ ─ HTTPサーバー(組み込みTomcat) │
│ ├── ルーティング(@GetMapping等) │
│ └── 設定管理(application.yml) │
│ │
│ idp-server が自作しているもの: │
│ ├── DIパターン(コンストラクタインジェクション) │
│ │ └→ @Autowired は使わず、明示的にコンストラクタで注入 │
│ ├── データアクセス層(独自Repository) │
│ │ └→ Spring Data JPA は使わず、独自実装 │
│ ├── セキュリティ(独自実装) │
│ │ └→ Spring Security は使わず、OAuth/OIDC仕様に準拠 │
│ ├── OAuth/OIDCプロトコル処理 │
│ ├── 認証ロジック │
│ ├── トークン発行・検証 │
│ └── マルチテナント管理 │
│ │
│ なぜ自作? │
│ ├── 仕様への厳密な準拠(Spring Security では制約がある) │
│ ├── 柔軟なカスタマイズ性 │
│ └── フレームワークの「魔法」を減らし、明示的なコードに │
│ │
└─────────────────────────────────────────────────────────────┘
まとめ
フレームワークの本質
┌─────────────────────────────────────────────────────────────┐
│ まとめ │
├─────────────────────────────────────────────────────────────┤
│ │
│ フレームワーク = アプリケーションの骨組み │
│ │
│ ライブラリとの違い: │
│ ・ライブラリ: あなたが呼び出す(道具) │
│ ・フレームワーク: あなたを呼び出す(枠組み) │
│ │
│ これを「制御の反転(IoC)」と呼ぶ │
│ │
│ フレームワークのメリット: │
│ ・車輪の再発明を防ぐ │
│ ・ベストプラクティスの適用 │
│ ・チーム開発の効率化 │
│ ・エコシステムの活用 │
│ │
│ フレームワークのデメリット: │
│ ・学習コストが高い │
│ ・入れ替えが困難 │
│ ・フレームワークの制約に縛られる │
│ │
└─────────────────────────────────────────────────────────────┘
覚えておくべきこと
| 概念 | 説明 |
|---|---|
| フレームワーク | アプリの骨組みを提供、あなたのコードを呼び出す |
| ライブラリ | 便利な機能を提供、あなたが呼び出す |
| IoC(制御の反転) | 制御の主導権がフレームワークにある |
| ハリウッドの原則 | "Don't call us, we'll call you" |
次のステップ
この入門が理解できたら、次に進みましょう。
練習問題
Q1: これはライブラリ?フレームワーク?
以下のそれぞれについて、ライブラリかフレームワークか答えてください。
- Gson(JSONパーサー)
- Spring Boot
- Apache Commons(ユーティリティ集)
- React
- JUnit
答えを見る
- Gson: ライブラリ(あなたが呼び出す)
- Spring Boot: フレームワーク(あなたのコードを呼び出す)
- Apache Commons: ライブラリ(便利な関数の集合)
- React: フレームワーク(コンポーネントをReactが呼び出す)
- JUnit: フレームワーク(テストメソッドをJUnitが呼び出す)
Q2: IoC を説明してください
「制御の反転」を、フレームワークを知らない人にも分かるように説明してください。
解答例
「普通は自分がプログラムの流れを決めて、必要なときに道具(ライブラリ)を使います。でもフレームワークでは逆で、フレームワークがプログラムの流れを決めて、必要なときに自分のコードを呼び出します。これが制御の反転です。
ファストフード店で例えると、普通のレストラン(ライ ブラリ)は好きな順番で料理を頼めますが、ファストフード店(フレームワーク)では決まった流れ(注文→支払い→受け取り)に従います。自分はその流れの中で『何を注文するか』だけを決めればいい、という感じです。」