【新人エンジニア向け】Gitグラフの読み方とクラス図について備忘録いろいろ
# 【新人エンジニア向け】Gitグラフの読み方完全ガイド
こんにちは。今日は、Gitのコミットグラフの読み方について、基礎から実践まで丁寧に解説いたしますね。
---
## 📚 Gitグラフとは?
**Gitグラフ**は、コードの変更履歴を視覚的に表現したものです。
- **いつ**変更が行われたか
- **誰が**変更したか
- **どのように**ブランチが分かれて合流したか
これらが一目で分かる、とても便利なツールなんです。
---
## 🎯 基本的な要素
### 1. コミット(●や*)
```
* ← これが1つのコミット
```
**コミット**とは:
- コードの変更を記録したもの
- スナップショット(写真)のようなもの
- 各コミットには固有のID(ハッシュ値)があります
**表示例:**
```
* abc1234 コミットメッセージ (田中, 2時間前)
```
- `abc1234`: コミットID
- `コミットメッセージ`: 何を変更したか
- `(田中, 2時間前)`: 誰がいつ変更したか
---
### 2. 線(|、/、\)
コミット同士のつながりを示します。
```
| ← 直線:同じブランチ上
/ ← 斜線:分岐や合流
\ ← 斜線:分岐や合流
```
---
### 3. ブランチ名
```
* abc1234 (HEAD -> main) コミットメッセージ
↑
現在いる場所
```
**重要な表記:**
- `HEAD`: 今作業している場所
- `main` または `master`: メインブランチ
- `origin/main`: リモート(サーバー上)のmainブランチ
- `feature/xxx`: 機能開発用ブランチ
---
## 📖 よく見るパターン
### パターン1: 直線的な履歴(シンプル)
```
* コミットD (HEAD -> main) 最新
|
* コミットC
|
* コミットB
|
* コミットA 最古
```
**読み方:**
1. 下から上に時系列で並んでいます
2. A → B → C → D の順番で変更されました
3. 1本の直線 = 1つのブランチだけ
4. 全て同じブランチ(main)上の変更
**こんな時に見られます:**
- 個人開発
- 一人で作業している時
- ブランチを切らずに開発している時
---
### パターン2: ブランチの分岐
```
* コミットD (feature) ← featureブランチ
|
| * コミットC (main) ← mainブランチ
|/
* コミットB ← 分岐点(共通の祖先)
|
* コミットA
```
**読み方:**
1. コミットBで2つに分かれました
2. 左側(`*`):featureブランチの変更
3. 右側(`* |`):mainブランチの変更
4. 2つのブランチが並行して開発されています
**実際の開発シーン:**
```
コミットB: 「OK、ここから新機能を作ろう」
↓ ブランチを作成(git checkout -b feature)
コミットD: 「新機能を実装中...」(featureブランチ)
コミットC: 「バグ修正」(mainブランチ)
```
---
### パターン3: マージ(合流)
```
* コミットE (main) ← マージコミット
|\
| * コミットD (feature)
* | コミットC
|/
* コミットB ← 共通の祖先
|
* コミットA
```
**読み方:**
1. コミットEで2つのブランチが合流しました
2. `|\` が合流点を示しています
3. featureブランチの変更がmainに取り込まれました
**実際の開発シーン:**
```
コミットB: 「ここから分岐」
コミットC: mainで「バグ修正」
コミットD: featureで「新機能完成」
コミットE: 「新機能をmainに取り込む」(git merge feature)
```
---
### パターン4: 複数ブランチの並行開発
```
* コミットG (feature2)
|
| * コミットF (feature1)
| |
* | コミットE (main)
| |
| * コミットD
|/
* コミットC
|
* コミットB
|
* コミットA
```
**読み方:**
1. 3つのブランチが同時に開発されています
2. main、feature1、feature2が並行して進んでいます
3. それぞれ独立した作業が行われています
**実際の開発シーン:**
```
田中さん: feature1で「ログイン機能」を開発中
佐藤さん: feature2で「決済機能」を開発中
山田さん: mainで「緊急バグ修正」
```
---
### パターン5: Fast-Forward マージ
```
【マージ前】
* コミットD (feature) ← これをmainに取り込みたい
|
* コミットC
|
* コミットB (main) ← mainはここで止まっている
|
* コミットA
【マージ後】
* コミットD (HEAD -> main, feature) ← mainが移動しただけ
|
* コミットC
|
* コミットB
|
* コミットA
```
**読み方:**
1. mainブランチが単純に前に進みました
2. 新しいマージコミットは作られていません
3. 履歴が一直線のまま
**こんな時に起こります:**
- featureブランチを作った後、mainに変更がない場合
- `git merge --ff feature` を実行した場合
---
## 🔍 見方のコツ
### コツ1: 色に注目する
多くのツールでは、ブランチごとに色分けされています。
```
* (青) main ブランチのコミット
* (緑) feature ブランチのコミット
* (赤) hotfix ブランチのコミット
```
**同じ色 = 同じブランチ**と覚えましょう。
---
### コツ2: 合流点を探す
```
* ← この位置にマージコミットがある
|\
```
- `*` と `\` の組み合わせがマージ
- ここでブランチが1つにまとまっています
---
### コツ3: 分岐点を探す
```
*
|
| * ← ここで分かれた
|/
*
```
- `/` の位置が分岐点
- ここから別の作業が始まりました
---
### コツ4: HEADの位置を確認
```
* abc1234 (HEAD -> feature) ← 今ここにいます
|
* def5678 (main)
```
- `HEAD`: 今作業している位置
- `->`: どのブランチにいるか
- 上記の例では「featureブランチで作業中」
---
## 📊 実践的な読み方
### 例1: 機能開発の流れ
```
* abc1234 (HEAD -> main) Merge branch 'feature/login' ⑤
|\
| * def5678 (feature/login) ログイン機能完成 ④
| * ghi9012 ログイン画面作成 ③
* | jkl3456 バグ修正 ②
|/
* mno7890 初期コミット ①
```
**ストーリー:**
1. ① 初期コミット:プロジェクト開始
2. ② mainでバグ修正:緊急対応
3. ③ featureブランチでログイン画面作成
4. ④ featureブランチでログイン機能完成
5. ⑤ featureブランチをmainにマージ
---
### 例2: コンフリクト(衝突)が起きそうな状態
```
* コミットD (feature) index.htmlを編集 ← 同じファイル
|
| * コミットC (main) index.htmlを編集 ← 同じファイル
|/
* コミットB
```
**注意サイン:**
- 両方のブランチで同じファイルを編集している
- マージ時にコンフリクトが発生する可能性が高い
**対処方法:**
1. mainの最新を確認:`git checkout main && git pull`
2. featureにmainを取り込む:`git checkout feature && git merge main`
3. コンフリクトを解決
4. mainにマージ:`git checkout main && git merge feature`
---
### 例3: リモートとローカルの状態
```
* abc1234 (HEAD -> main) ローカルの最新 ← ローカル
|
* def5678 (origin/main) リモートの最新 ← サーバー上
|
* ghi9012 過去のコミット
```
**読み方:**
- `main`: ローカル(自分のPC)のブランチ
- `origin/main`: リモート(GitHub等)のブランチ
- ローカルがリモートより1つ進んでいる
- `git push` でリモートに反映できる
**逆パターン:**
```
* abc1234 (origin/main) リモートの最新 ← サーバー上
|
* def5678 (HEAD -> main) ローカルの最新 ← ローカル
```
- リモートがローカルより進んでいる
- `git pull` でローカルを最新にする必要がある
---
## 🛠️ よく使うGitコマンドとグラフの変化
### コマンド1: git log --graph
```bash
git log --graph --oneline --all
```
**出力例:**
```
* abc1234 (HEAD -> main) 最新コミット
* def5678 2つ目のコミット
* ghi9012 最初のコミット
```
---
### コマンド2: git log --graph --all --decorate
```bash
git log --graph --all --decorate --oneline
```
**出力例:**
```
* abc1234 (HEAD -> main) Merge branch 'feature'
|\
| * def5678 (feature) 機能追加
* | ghi9012 バグ修正
|/
* jkl3456 初期コミット
```
---
### コマンド3: git branch --all
現在のブランチ一覧を表示:
```bash
git branch --all
```
**出力例:**
```
* main ← 今ここにいる
feature/login
remotes/origin/main
remotes/origin/feature/login
```
---
## 📋 チェックリスト:グラフが読めているか確認
### ✅ 基本的な読み方
- [ ] コミットの新旧が分かる(下→上、左→右)
- [ ] どのブランチのコミットか分かる
- [ ] 今どこで作業しているか分かる(HEAD)
- [ ] 分岐点が分かる
- [ ] 合流点が分かる
### ✅ 実践的な読み方
- [ ] 誰がいつコミットしたか分かる
- [ ] どのファイルが変更されたか推測できる
- [ ] コンフリクトが起きそうな状態が分かる
- [ ] リモートとローカルの差分が分かる
- [ ] マージすべきタイミングが分かる
---
## 🎓 練習問題
### 問題1: このグラフを説明してください
```
* Merge branch 'feature'
|\
| * 新機能追加
* | バグ修正
|/
* 初期コミット
```
<details>
<summary>答えを見る</summary>
**説明:**
1. 初期コミットから2つのブランチに分かれました
2. 一方で「新機能追加」、もう一方で「バグ修正」が行われました
3. 最後に2つのブランチが合流しました(マージ)
4. 並行して開発が進められていた様子が分かります
</details>
---
### 問題2: このグラフで問題が起きそうな箇所は?
```
* (feature) index.htmlを修正
|
| * (main) index.htmlを修正
|/
* 初期コミット
```
<details>
<summary>答えを見る</summary>
**問題点:**
- 両方のブランチで同じファイル(index.html)を修正しています
- マージ時にコンフリクト(衝突)が発生する可能性が高いです
**対処方法:**
1. 先にmainの変更をfeatureに取り込む
2. コンフリクトを解決
3. その後でfeatureをmainにマージ
</details>
---
## 💡 実務でのポイント
### ポイント1: こまめに確認
```bash
# 現在の状態を確認
git status
# グラフを確認
git log --graph --oneline --all
# リモートの状態を確認
git fetch
git log --graph --oneline --all
```
---
### ポイント2: ブランチ名に意味を持たせる
**良い例:**
```
feature/login ← ログイン機能
feature/payment ← 決済機能
hotfix/bug-123 ← バグ修正
release/v1.0 ← リリース準備
```
**悪い例:**
```
test
new-branch
tmp
branch1
```
---
### ポイント3: 定期的にmainを取り込む
```bash
# featureブランチで作業中
git checkout feature
# mainの最新を取り込む
git merge main
# コンフリクトがあれば解決
# ...
# 作業を続ける
```
こうすることで:
- 大きなコンフリクトを防げます
- 最新のコードで開発できます
- マージが楽になります
---
## 🎯 まとめ
### 覚えておきたい3つのポイント
1. **`*` がコミット、`|` が線**
- グラフの基本要素
2. **`/` と `\` が分岐・合流**
- ブランチの動きが分かる
3. **`HEAD` が今の位置**
- 自分がどこにいるか確認
### 次のステップ
1. ✅ **実際にGitグラフを見てみる**
- GitHub Desktop
- SourceTree
- GitKraken
- VS Codeの拡張機能
2. ✅ **自分でブランチを作って試す**
```bash
git checkout -b test-branch
# 何か変更
git commit -m "テスト"
git log --graph --all --oneline
```
3. ✅ **チームの開発フローを理解する**
- どういうブランチ戦略を使っているか
- いつマージするか
- コードレビューのタイミング
---
この記事が、皆さまのGit理解の助けになれば嬉しいです!
最初は難しく感じるかもしれませんが、慣れれば直感的に読めるようになります。
一緒に頑張りましょう!✨
#Git #バージョン管理 #新人エンジニア #開発フロー #チーム開発
---
## 📥 Excel版ダウンロード用データ
### シート1: 基本パターン集
| パターン | 図 | 説明| 使用場面 |
|---------|--¥---|------|---------|
| 直線 | `* → * → *` | 1本のブランチ | 個人開発 |
| 分岐 | `* / * \ *` | ブランチ作成 | 機能開発開始 |
| 合流 | `* \ * / *` | マージ | 機能完成 |
### シート2: よくある問題と解決策
| 問題 | グラフ | 解決策 |
|-----|-------|--------|
| コンフリクト | 両方で同じファイル編集 | mainを先に取り込む |
| リモートと差分 | origin/mainが先 | git pull |
| プッシュできない | ローカルが古い | git pull → git push |
### シート3: コマンド一覧
| コマンド | 説明 | 使用タイミング |
|---------|-----|--------------|
| `git log --graph` | グラフ表示 | 履歴確認時 |
| `git branch` | ブランチ一覧 | 現在地確認時 |
| `git status` | 状態確認 | 常時 |

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>UMLクラス図テンプレート - Excel形式</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', 'Yu Gothic', sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 20px;
min-height: 100vh;
}
.container {
max-width: 1200px;
margin: 0 auto;
background: white;
border-radius: 20px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
overflow: hidden;
}
.header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 40px;
text-align: center;
}
.header h1 {
font-size: 2em;
margin-bottom: 10px;
}
.header p {
opacity: 0.9;
font-size: 1.1em;
}
.content {
padding: 40px;
}
.sheet-tabs {
display: flex;
gap: 10px;
margin-bottom: 30px;
border-bottom: 2px solid #e0e0e0 ;
}
.tab {
padding: 15px 30px;
background: #f5f5f5 ;
border: none;
cursor: pointer;
font-size: 1em;
font-weight: bold;
border-radius: 10px 10px 0 0;
transition: all 0.3s;
}
.tab.active {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
transform: translateY(-2px);
}
.sheet {
display: none;
}
.sheet.active {
display: block;
animation: fadeIn 0.5s;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
table {
width: 100%;
border-collapse: collapse;
margin-bottom: 30px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
border-radius: 10px;
overflow: hidden;
}
th {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 15px;
text-align: left;
font-weight: bold;
}
td {
padding: 12px 15px;
border-bottom: 1px solid #e0e0e0 ;
}
tr:hover {
background: #f8f9ff ;
}
.example-box {
background: #f0f7ff ;
border-left: 4px solid #667eea ;
padding: 20px;
margin: 20px 0;
border-radius: 5px;
}
.example-box h3 {
color: #667eea ;
margin-bottom: 15px;
}
.class-diagram {
background: white;
border: 2px solid #667eea ;
border-radius: 10px;
padding: 20px;
margin: 20px 0;
font-family: 'Courier New', monospace;
}
.class-name {
font-weight: bold;
font-size: 1.2em;
color: #667eea ;
text-align: center;
padding-bottom: 10px;
border-bottom: 2px solid #667eea ;
margin-bottom: 10px;
}
.attributes, .methods {
margin: 10px 0;
}
.section-title {
font-weight: bold;
color: #764ba2 ;
margin-top: 15px;
margin-bottom: 5px;
}
.download-btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 15px 40px;
border: none;
border-radius: 50px;
font-size: 1.1em;
font-weight: bold;
cursor: pointer;
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
transition: all 0.3s;
display: block;
margin: 30px auto;
}
.download-btn:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(102, 126, 234, 0.6);
}
.tips {
background: #fff3cd ;
border-left: 4px solid #ffc107 ;
padding: 15px;
margin: 20px 0;
border-radius: 5px;
}
.tips h4 {
color: #856404 ;
margin-bottom: 10px;
}
.relationship-diagram {
text-align: center;
padding: 20px;
background: #f8f9fa ;
border-radius: 10px;
margin: 20px 0;
font-family: monospace;
font-size: 0.9em;
}
code {
background: #f4f4f4 ;
padding: 2px 6px;
border-radius: 3px;
font-family: 'Courier New', monospace;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>📊 UMLクラス図テンプレート</h1>
<p>新人エンジニア向け - Excel形式ダウンロード可能</p>
</div>
<div class="content">
<div class="sheet-tabs">
<button class="tab active" onclick="showSheet(1)">シート1:テンプレート</button>
<button class="tab" onclick="showSheet(2)">シート2:記入例</button>
<button class="tab" onclick="showSheet(3)">シート3:関係性一覧</button>
<button class="tab" onclick="showSheet(4)">シート4:記載ポイント</button>
</div>
<!-- シート1:テンプレート -->
<div class="sheet active" id="sheet1">
<h2 style="color: #667eea ; margin-bottom: 20px;">📝 クラス図テンプレート</h2>
<table>
<thead>
<tr>
<th>項目</th>
<th>内容</th>
<th>記入例</th>
<th>メモ(記載ポイント)</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>クラス名</strong></td>
<td>クラスの名前を記載</td>
<td><code>User</code></td>
<td>名詞で統一。1クラス=1役割を意識。</td>
</tr>
<tr>
<td><strong>説明</strong></td>
<td>クラスの目的や役割を簡潔に記述</td>
<td>「ユーザー情報を管理するクラス」</td>
<td>一文で機能を説明すると見やすい。</td>
</tr>
<tr>
<td><strong>属性(フィールド)</strong></td>
<td>クラスが持つデータ項目</td>
<td><code>user_id: int</code><br><code>email: str</code><br><code>created_at: datetime</code></td>
<td>「変数名: 型」で書く。アクセス修飾子(+/-/#)を付けてもOK。</td>
</tr>
<tr>
<td><strong>操作(メソッド)</strong></td>
<td>クラスが持つ処理</td>
<td><code>login()</code><br><code>update_email()</code><br><code>delete_account()</code></td>
<td>動詞で統一。機能単位で命名。</td>
</tr>
<tr>
<td><strong>アクセス修飾子</strong></td>
<td>公開範囲を明示</td>
<td><code>+ public</code><br><code>- private</code><br><code># protected</code></td>
<td>クラス図では簡略記号で表現可能。</td>
</tr>
<tr>
<td><strong>関連(Association)</strong></td>
<td>他クラスとの関係</td>
<td><code>User 1 --- * Order</code></td>
<td>1対多(1..*)や依存関係(→)を矢印で表す。</td>
</tr>
<tr>
<td><strong>継承(Generalization)</strong></td>
<td>継承関係を表現</td>
<td><code>AdminUser ⟶ User</code></td>
<td>三角矢印(▷)で表記。</td>
</tr>
<tr>
<td><strong>依存(Dependency)</strong></td>
<td>あるクラスが他クラスを利用</td>
<td><code>Order ⟶ Product</code></td>
<td>メソッド内で利用する関係を示す。</td>
</tr>
<tr>
<td><strong>集約・合成</strong></td>
<td>部分と全体の関係</td>
<td><code>Team ◇── Member</code>(集約)<br><code>Team ◆── Member</code>(合成)</td>
<td>白菱形=集約、黒菱形=合成。</td>
</tr>
</tbody>
</table>
<div class="tips">
<h4>💡 記載のポイント</h4>
<ul>
<li>クラス図は <strong>上:クラス名 → 中:属性 → 下:操作(メソッド)</strong> の3段構造で書く</li>
<li>共通処理はスーパークラスにまとめ、重複を避ける</li>
<li>関連線に <strong>多重度(1、0..1、1..*)</strong> を書くと、データ構造が理解しやすい</li>
<li>操作(メソッド)は <strong>処理の責任を持つクラス</strong> に置く</li>
</ul>
</div>
</div>
<!-- シート2:記入例 -->
<div class="sheet" id="sheet2">
<h2 style="color: #667eea ; margin-bottom: 20px;">📖 記入例:User - Order - Product</h2>
<div class="example-box">
<h3>クラス1: User(ユーザー)</h3>
<div class="class-diagram">
<div class="class-name">User</div>
<div class="section-title">属性(Attributes)</div>
<div class="attributes">
- user_id: int<br>
- email: str<br>
- username: str<br>
- password_hash: str<br>
- created_at: datetime
</div>
<div class="section-title">操作(Methods)</div>
<div class="methods">
+ login(): bool<br>
+ logout(): void<br>
+ update_email(new_email: str): void<br>
+ delete_account(): void<br>
- validate_password(password: str): bool
</div>
</div>
</div>
<div class="example-box">
<h3>クラス2: Order(注文)</h3>
<div class="class-diagram">
<div class="class-name">Order</div>
<div class="section-title">属性(Attributes)</div>
<div class="attributes">
- order_id: int<br>
- user_id: int<br>
- total_amount: float<br>
- status: str<br>
- order_date: datetime
</div>
<div class="section-title">操作(Methods)</div>
<div class="methods">
+ create_order(): void<br>
+ cancel_order(): bool<br>
+ calculate_total(): float<br>
+ add_product(product: Product, quantity: int): void<br>
+ get_order_details(): dict
</div>
</div>
</div>
<div class="example-box">
<h3>クラス3: Product(商品)</h3>
<div class="class-diagram">
<div class="class-name">Product</div>
<div class="section-title">属性(Attributes)</div>
<div class="attributes">
- product_id: int<br>
- name: str<br>
- price: float<br>
- stock: int<br>
- description: str
</div>
<div class="section-title">操作(Methods)</div>
<div class="methods">
+ get_price(): float<br>
+ update_stock(quantity: int): void<br>
+ is_available(): bool<br>
- calculate_discount(rate: float): float
</div>
</div>
</div>
<div class="relationship-diagram">
<h3 style="margin-bottom: 15px;">クラス間の関係</h3>
<pre style="text-align: left; display: inline-block;">
┌──────────────┐
│ User │
└──────────────┘
│ 1
│ 持つ
│
│ *
┌──────────────┐
│ Order │
└──────────────┘
│ *
│ 含む
│
│ *
┌──────────────┐
│ Product │
└──────────────┘
関係性の説明:
• User 1 ─── * Order : 1人のユーザーは複数の注文を持つ
• Order * ─── * Product : 1つの注文は複数の商品を含む
</pre>
</div>
</div>
<!-- シート3:関係性一覧 -->
<div class="sheet" id="sheet3">
<h2 style="color: #667eea ; margin-bottom: 20px;">🔗 クラス間の関係性一覧</h2>
<table>
<thead>
<tr>
<th>関係の種類</th>
<th>UML記号</th>
<th>意味</th>
<th>具体例</th>
<th>使い分け</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>関連<br>(Association)</strong></td>
<td><code>A ───── B</code></td>
<td>一般的な関連</td>
<td>User ───── Order<br>(ユーザーは注文を持つ)</td>
<td>基本的な「持っている」関係</td>
</tr>
<tr>
<td><strong>方向付き関連</strong></td>
<td><code>A ────→ B</code></td>
<td>一方向の関連</td>
<td>Order ────→ Product<br>(注文は商品を参照)</td>
<td>片方だけが相手を知っている</td>
</tr>
<tr>
<td><strong>継承<br>(Generalization)</strong></td>
<td><code>A ─────▷ B</code></td>
<td>is-a関係<br>(AはBである)</td>
<td>AdminUser ─────▷ User<br>(管理者ユーザーはユーザーである)</td>
<td>クラスの汎化・特化</td>
</tr>
<tr>
<td><strong>実装<br>(Realization)</strong></td>
<td><code>A ─ ─ ─▷ B</code><br>(点線)</td>
<td>インターフェース実装</td>
<td>UserService ─ ─ ─▷ IUserService<br>(サービスはインターフェースを実装)</td>
<td>インターフェースとの関係</td>
</tr>
<tr>
<td><strong>依存<br>(Dependency)</strong></td>
<td><code>A ─ ─ ─→ B</code><br>(点線矢印)</td>
<td>use関係<br>(AはBを使う)</td>
<td>OrderController ─ ─ ─→ Order<br>(コントローラーは注文を使う)</td>
<td>メソッド内で一時的に利用</td>
</tr>
<tr>
<td><strong>集約<br>(Aggregation)</strong></td>
<td><code>A ◇───── B</code><br>(白菱形)</td>
<td>has-a関係(弱い)<br>部分は独立可能</td>
<td>Team ◇───── Member<br>(チームはメンバーを持つ)<br>※メンバーはチーム解散後も存在</td>
<td>部分が独立して存在できる</td>
</tr>
<tr>
<td><strong>合成<br>(Composition)</strong></td>
<td><code>A ◆───── B</code><br>(黒菱形)</td>
<td>has-a関係(強い)<br>部分は全体に依存</td>
<td>Order ◆───── OrderItem<br>(注文は注文明細を持つ)<br>※注文が削除されれば明細も削除</td>
<td>部分が全体に完全依存</td>
</tr>
</tbody>
</table>
<div class="tips">
<h4>💡 多重度(Multiplicity)の表記</h4>
<table style="margin-top: 10px;">
<tr>
<th>表記</th>
<th>意味</th>
<th>例</th>
</tr>
<tr>
<td><code>1</code></td>
<td>必ず1つ</td>
<td>1人のユーザー</td>
</tr>
<tr>
<td><code>0..1</code></td>
<td>0または1つ</td>
<td>プロフィール画像(あってもなくてもOK)</td>
</tr>
<tr>
<td><code>*</code></td>
<td>0以上</td>
<td>複数の注文</td>
</tr>
<tr>
<td><code>1..*</code></td>
<td>1以上</td>
<td>最低1つの商品</td>
</tr>
<tr>
<td><code>0..5</code></td>
<td>0〜5個</td>
<td>最大5つまでの画像</td>
</tr>
</table>
</div>
</div>
<!-- シート4:記載ポイント -->
<div class="sheet" id="sheet4">
<h2 style="color: #667eea ; margin-bottom: 20px;">📌 実務で使える記載ポイント</h2>
<div class="example-box">
<h3>1. クラス名の付け方</h3>
<table>
<tr>
<th>ルール</th>
<th>良い例</th>
<th>悪い例</th>
</tr>
<tr>
<td>名詞で命名</td>
<td><code>User</code>, <code>Order</code>, <code>Product</code></td>
<td><code>CreateUser</code>, <code>DoOrder</code></td>
</tr>
<tr>
<td>単数形を使う</td>
<td><code>Product</code></td>
<td><code>Products</code></td>
</tr>
<tr>
<td>パスカルケース</td>
<td><code>ShoppingCart</code></td>
<td><code>shopping_cart</code>, <code>shoppingcart</code></td>
</tr>
<tr>
<td>意味のある名前</td>
<td><code>PaymentProcessor</code></td>
<td><code>Manager</code>, <code>Handler</code></td>
</tr>
</table>
</div>
<div class="example-box">
<h3>2. 属性(フィールド)の記載ルール</h3>
<ul>
<li><strong>書式:</strong> <code>アクセス修飾子 属性名: 型 = デフォルト値</code></li>
<li><strong>例:</strong> <code>- email: str</code>, <code>+ user_id: int</code></li>
<li><strong>命名:</strong> スネークケース(Python)またはキャメルケース(Java)</li>
<li><strong>型を明記:</strong> 必ず型を書く(int, str, bool, datetime等)</li>
</ul>
<table style="margin-top: 15px;">
<tr>
<th>記号</th>
<th>意味</th>
<th>使用例</th>
</tr>
<tr>
<td><code>+</code></td>
<td>public(公開)</td>
<td><code>+ user_id: int</code></td>
</tr>
<tr>
<td><code>-</code></td>
<td>private(非公開)</td>
<td><code>- password_hash: str</code></td>
</tr>
<tr>
<td><code>#</code></td>
<td>protected(継承先に公開)</td>
<td><code># created_at: datetime</code></td>
</tr>
<tr>
<td><code>~</code></td>
<td>package(同一パッケージ内)</td>
<td><code>~ internal_id: int</code></td>
</tr>
</table>
</div>
<div class="example-box">
<h3>3. メソッド(操作)の記載ルール</h3>
<ul>
<li><strong>書式:</strong> <code>アクセス修飾子 メソッド名(引数: 型): 戻り値の型</code></li>
<li><strong>例:</strong> <code>+ login(email: str, password: str): bool</code></li>
<li><strong>命名:</strong> 動詞で始める(get, set, create, update, delete等)</li>
<li><strong>責任を明確に:</strong> 1メソッド1責任を心がける</li>
</ul>
<table style="margin-top: 15px;">
<tr>
<th>用途</th>
<th>命名パターン</th>
<th>例</th>
</tr>
<tr>
<td>取得</td>
<td>get〜, find〜</td>
<td><code>get_user(), find_by_email()</code></td>
</tr>
<tr>
<td>設定</td>
<td>set〜, update〜</td>
<td><code>set_email(), update_password()</code></td>
</tr>
<tr>
<td>作成</td>
<td>create〜, add〜</td>
<td><code>create_order(), add_item()</code></td>
</tr>
<tr>
<td>削除</td>
<td>delete〜, remove〜</td>
<td><code>delete_account(), remove_item()</code></td>
</tr>
<tr>
<td>判定</td>
<td>is〜, has〜, can〜</td>
<td><code>is_valid(), has_permission()</code></td>
</tr>
</table>
</div>
<div class="example-box">
<h3>4. よくある設計パターン</h3>
<h4 style="margin-top: 15px;">パターン1: 継承(Generalization)</h4>
<pre style="background: #f8f9fa ; padding: 15px; border-radius: 5px;">
Person(親クラス)
▲
│
┌──────┴──────┐
│ │
Employee Customer
(従業員) (顧客)
</pre>
<h4 style="margin-top: 20px;">パターン2: 集約(Aggregation)</h4>
<pre style="background: #f8f9fa ; padding: 15px; border-radius: 5px;">
Company ◇───── Employee
(会社は従業員を持つが、会社がなくなっても従業員は存在する)
</pre>
<h4 style="margin-top: 20px;">パターン3: 合成(Composition)</h4>
<pre style="background: #f8f9fa ; padding: 15px; border-radius: 5px;">
Order ◆───── OrderItem
(注文は注文明細を持ち、注文が削除されれば明細も削除される)
</pre>
</div>
<div class="tips">
<h4>💡 設計のベストプラクティス</h4>
<ol>
<li><strong>単一責任の原則:</strong> 1クラスは1つの責任のみを持つ</li>
<li><strong>開放閉鎖の原則:</strong> 拡張に開いて、修正に閉じている</li>
<li><strong>リスコフの置換原則:</strong> 派生クラスは基底クラスと置き換え可能</li>
<li><strong>インターフェース分離の原則:</strong> 使わないインターフェースに依存しない</li>
<li><strong>依存性逆転の原則:</strong> 抽象に依存し、具象に依存しない</li>
</ol>
</div>
</div>
<button class="download-btn" onclick="downloadAsCSV()">
📥 Excel/CSV形式でダウンロード
</button>
<div class="tips" style="text-align: center; margin-top: 20px;">
<p><strong>💡 ダウンロード後の使い方</strong></p>
<p>ExcelまたはGoogleスプレッドシートで開いて、自由に編集してください。</p>
<p>各シートのテンプレートを参考に、プロジェクトのクラス図を作成できます!</p>
</div>
</div>
</div>
<script>
function showSheet(sheetNumber) {
// すべてのシートとタブを非アクティブに
const sheets = document.querySelectorAll('.sheet');
const tabs = document.querySelectorAll('.tab');
sheets.forEach(sheet => sheet.classList.remove('active'));
tabs.forEach(tab => tab.classList.remove('active'));
// 指定されたシートとタブをアクティブに
document.getElementById(`sheet${sheetNumber}`).classList.add('active');
tabs[sheetNumber - 1].classList.add('active');
}
function downloadAsCSV() {
// CSV形式のデータを作成
const csvData = generateCSVData();
// Blobを作成
const blob = new Blob([csvData], { type: 'text/csv;charset=utf-8;' });
// ダウンロードリンクを作成
const link = document.createElement('a');
const url = URL.createObjectURL(blob);
link.setAttribute('href', url);
link.setAttribute('download', 'UMLクラス図テンプレート.csv');
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
// 成功メッセージ
alert('✅ ダウンロードが完了しました!\n\nExcelまたはGoogleスプレッドシートで開いてご利用ください。');
}
function generateCSVData() {
let csv = '\uFEFF'; // BOM for UTF-8
// シート1: テンプレート
csv += '=== シート1: クラス図テンプレート ===\n';
csv += '項目,内容,記入例,メモ(記載ポイント)\n';
csv += 'クラス名,クラスの名前を記載,User,名詞で統一。1クラス=1役割を意識。\n';
csv += '説明,クラスの目的や役割を簡潔に記述,「ユーザー情報を管理するクラス」,一文で機能を説明すると見やすい。\n';
csv += '属性(フィールド),クラスが持つデータ項目,"user_id: int / email: str / created_at: datetime",「変数名: 型」で書く。アクセス修飾子(+/-/#)を付けてもOK。\n';
csv += '操作(メソッド),クラスが持つ処理,"login() / update_email() / delete_account()",動詞で統一。機能単位で命名。\n';
csv += 'アクセス修飾子,公開範囲を明示,"+ public / - private / # protected",クラス図では簡略記号で表現可能。\n';
csv += '関連(Association),他クラスとの関係,User 1 --- * Order,1対多(1..*)や依存関係(→)を矢印で表す。\n';
csv += '継承(Generalization),継承関係を表現,AdminUser ⟶ User,三角矢印(▷)で表記。\n';
csv += '依存(Dependency),あるクラスが他クラスを利用,Order ⟶ Product,メソッド内で利用する関係を示す。\n';
csv += '集約・合成,部分と全体の関係,"Team ◇── Member(集約) / Team ◆── Member(合成)",白菱形=集約、黒菱形=合成。\n';
csv += '\n\n';
// シート2: 記入例
csv += '=== シート2: 記入例(User - Order - Product) ===\n';
csv += '\n--- Userクラス ---\n';
csv += 'クラス名,User\n';
csv += '説明,ユーザー情報を管理するクラス\n';
csv += '属性,- user_id: int\n';
csv += ',- email: str\n';
csv += ',- username: str\n';
csv += ',- password_hash: str\n';
csv += ',- created_at: datetime\n';
csv += 'メソッド,+ login(): bool\n';
csv += ',+ logout(): void\n';
csv += ',+ update_email(new_email: str): void\n';
csv += ',+ delete_account(): void\n';
csv += ',- validate_password(password: str): bool\n';
csv += '\n--- Orderクラス ---\n';
csv += 'クラス名,Order\n';
csv += '説明,注文情報を管理するクラス\n';
csv += '属性,- order_id: int\n';
csv += ',- user_id: int\n';
csv += ',- total_amount: float\n';
csv += ',- status: str\n';
csv += ',- order_date: datetime\n';
csv += 'メソッド,+ create_order(): void\n';
csv += ',+ cancel_order(): bool\n';
csv += ',+ calculate_total(): float\n';
csv += ',+ add_product(product: Product / quantity: int): void\n';
csv += ',+ get_order_details(): dict\n';
csv += '\n--- Productクラス ---\n';
csv += 'クラス名,Product\n';
csv += '説明,商品情報を管理するクラス\n';
csv += '属性,- product_id: int\n';
csv += ',- name: str\n';
csv += ',- price: float\n';
csv += ',- stock: int\n';
csv += ',- description: str\n';
csv += 'メソッド,+ get_price(): float\n';
csv += ',+ update_stock(quantity: int): void\n';
csv += ',+ is_available(): bool\n';
csv += ',- calculate_discount(rate: float): float\n';
csv += '\n--- クラス間の関係 ---\n';
csv += '関係,User 1 --- * Order(1人のユーザーは複数の注文を持つ)\n';
csv += ',Order * --- * Product(1つの注文は複数の商品を含む)\n';
csv += '\n\n';
// シート3: 関係性一覧
csv += '=== シート3: クラス間の関係性一覧 ===\n';
csv += '関係の種類,UML記号,意味,具体例,使い分け\n';
csv += '関連(Association),A ───── B,一般的な関連,User ───── Order(ユーザーは注文を持つ),基本的な「持っている」関係\n';
csv += '方向付き関連,A ────→ B,一方向の関連,Order ────→ Product(注文は商品を参照),片方だけが相手を知っている\n';
csv += '継承(Generalization),A ─────▷ B,is-a関係(AはBである),AdminUser ─────▷ User(管理者ユーザーはユーザーである),クラスの汎化・特化\n';
csv += '実装(Realization),A ─ ─ ─▷ B(点線),インターフェース実装,UserService ─ ─ ─▷ IUserService,インターフェースとの関係\n';
csv += '依存(Dependency),A ─ ─ ─→ B(点線矢印),use関係(AはBを使う),OrderController ─ ─ ─→ Order,メソッド内で一時的に利用\n';
csv += '集約(Aggregation),A ◇───── B(白菱形),has-a関係(弱い)部分は独立可能,Team ◇───── Member,部分が独立して存在できる\n';
csv += '合成(Composition),A ◆───── B(黒菱形),has-a関係(強い)部分は全体に依存,Order ◆───── OrderItem,部分が全体に完全依存\n';
csv += '\n--- 多重度(Multiplicity)の表記 ---\n';
csv += '表記,意味,例\n';
csv += '1,必ず1つ,1人のユーザー\n';
csv += '0..1,0または1つ,プロフィール画像(あってもなくてもOK)\n';
csv += '*,0以上,複数の注文\n';
csv += '1..*,1以上,最低1つの商品\n';
csv += '0..5,0〜5個,最大5つまでの画像\n';
csv += '\n\n';
// シート4: 記載ポイント
csv += '=== シート4: 実務で使える記載ポイント ===\n';
csv += '\n--- 1. クラス名の付け方 ---\n';
csv += 'ルール,良い例,悪い例\n';
csv += '名詞で命名,User / Order / Product,CreateUser / DoOrder\n';
csv += '単数形を使う,Product,Products\n';
csv += 'パスカルケース,ShoppingCart,shopping_cart / shoppingcart\n';
csv += '意味のある名前,PaymentProcessor,Manager / Handler\n';
csv += '\n--- 2. 属性の記載ルール ---\n';
csv += '書式,アクセス修飾子 属性名: 型 = デフォルト値\n';
csv += '例,- email: str / + user_id: int\n';
csv += '命名,スネークケース(Python)またはキャメルケース(Java)\n';
csv += '型を明記,必ず型を書く(int / str / bool / datetime等)\n';
csv += '\n--- アクセス修飾子 ---\n';
csv += '記号,意味,使用例\n';
csv += '+,public(公開),+ user_id: int\n';
csv += '-,private(非公開),- password_hash: str\n';
csv += '#,protected(継承先に公開),# created_at: datetime\n';
csv += '~,package(同一パッケージ内),~ internal_id: int\n';
csv += '\n--- 3. メソッドの記載ルール ---\n';
csv += '書式,アクセス修飾子 メソッド名(引数: 型): 戻り値の型\n';
csv += '例,+ login(email: str / password: str): bool\n';
csv += '命名,動詞で始める(get / set / create / update / delete等)\n';
csv += '責任を明確に,1メソッド1責任を心がける\n';
csv += '\n--- メソッド命名パターン ---\n';
csv += '用途,命名パターン,例\n';
csv += '取得,get〜 / find〜,get_user() / find_by_email()\n';
csv += '設定,set〜 / update〜,set_email() / update_password()\n';
csv += '作成,create〜 / add〜,create_order() / add_item()\n';
csv += '削除,delete〜 / remove〜,delete_account() / remove_item()\n';
csv += '判定,is〜 / has〜 / can〜,is_valid() / has_permission()\n';
csv += '\n--- 設計のベストプラクティス ---\n';
csv += '1. 単一責任の原則,1クラスは1つの責任のみを持つ\n';
csv += '2. 開放閉鎖の原則,拡張に開いて / 修正に閉じている\n';
csv += '3. リスコフの置換原則,派生クラスは基底クラスと置き換え可能\n';
csv += '4. インターフェース分離の原則,使わないインターフェースに依存しない\n';
csv += '5. 依存性逆転の原則,抽象に依存し / 具象に依存しない\n';
csv += '\n\n';
// 使い方ガイド
csv += '=== 使い方ガイド ===\n';
csv += '1. このCSVファイルをExcelまたはGoogleスプレッドシートで開く\n';
csv += '2. 各シートのテンプレートを参考に、自分のプロジェクトのクラス図を作成\n';
csv += '3. 「===」で区切られた各セクションを別シートにコピーすると見やすい\n';
csv += '4. 必要に応じてセルを結合したり、色を付けたりしてカスタマイズ\n';
csv += '\n記載ポイント:\n';
csv += '• クラス図は 上:クラス名 → 中:属性 → 下:操作(メソッド) の3段構造\n';
csv += '• 共通処理はスーパークラスにまとめ、重複を避ける\n';
csv += '• 関連線に 多重度(1、0..1、1..*) を書くと理解しやすい\n';
csv += '• 操作(メソッド)は 処理の責任を持つクラス に置く\n';
csv += '\n作成者: Python先生 / 作成日: 2025年\n';
csv += 'このテンプレートは自由に編集・配布できます。\n';
return csv;
}
</script>
</body>
</html>