オブジェクト指向知識体系

# 目次

- 挨拶
- オブジェクト指向とは
    - システム開発を楽にする総合技術
- オブジェクト指向プログラミング
    - 構造化言語と機能中心開発
    - OOPの特徴
- 再利用可能な部品群
    - フレームワーク
    - デザインパターン
- 汎用分析手法
    - 集合論, 役割分担とメッセージパッシング
- 上流工程
    - 業務分析・モデリング
- 反復開発手法
    - XP
    - スクラム
    - アジャイル
        - TDD
        - リファクタリング
        - CI
- まとめ

# 挨拶

この記事をご覧になってくださった皆様、ありがとうございます。

石川 聖(ヒジリ)と申します。

先日の「自己紹介&ポートフォリオ作成」に続き4本めの投稿になります。

宜しければご覧になってください。

https://qiita.com/ishikawahijiri/items/233f353b274a8a514350

この記事では、オブジェクト指向について概要を解説していきます。

現在、メジャーなパラダイムとなっているオブジェクト指向プログラミングや、その歴史的背景、上流工程への適応を簡単に解説していきます。

(今後の記事で個別具体的に掘り下げていきます。)

# オブジェクト指向とは

Java や Pythonなどのメジャーな言語を学び始めると、「オブジェクト指向」という言葉をよく聞くようになり、勉強しようと思う人も多いると思います。

でも、駆け出しのプログラマだと「クラス？継承？…なんか難しそう」と感じてしまうことも多いと思います。

そんな方のために、この記事ではオブジェクト指向の知識体系について易しく解説していきます。

いきなり結論ですが、オブジェクト指向とは要するに

- ソフトウェア開発を楽にするための総合技術

と言えます。

オブジェクト指向は、ただのプログラミングスタイルではなく、要件定義や設計、テスト、保守など、ソフトウェア開発のあらゆる工程で活用される考え方・技術の集合体です。

### オブジェクト指向の構成要素

以下のように、オブジェクト指向は多岐にわたる知識体系から成り立っています。

1. プログラミング言語のパラダイム

    - Java、Python、C#など多くの言語がオブジェクト指向をサポート
    - - クラスやオブジェクトを使ってデータと振る舞いをまとめる

2. 業務分析・設計の図式表現

    - UML（統一モデリング言語）を使って、業務やシステムの構造を「見える化」する

3. 再利用可能な部品群

    - フレームワークやライブラリの多くは、オブジェクト指向をベースに構築されている
    - 再利用性や拡張性の高い設計が可能に

4. 優れた設計のノウハウ集

    - GoFのデザインパターン（Strategy, Singletonなど）をはじめとするベストプラクティス

5. 要件定義や業務モデリングの技法

    - UMLによる分析だけでなく、集合論的なモデル、役割分担とメッセージパッシングの考え方なども含む

6. 柔軟なソフトウェア開発手法

    - オブジェクト指向にフィットする反復的な開発プロセス
        - XP（エクストリーム・プログラミング）
        - スクラム
        - アジャイル開発
            - TDD（テスト駆動開発）
            - リファクタリング
            - CI（継続的インテグレーション）

### なぜこんなに広範囲に？

「オブジェクト指向」と一言で言っても、上記のそれぞれの中身は多種多様に全く異なるものです。

しかし、これらは

- **「ソフトウェア開発をよりよくするための技術や考え方」**

という点で共通しています。

設計から開発、保守まで、ほぼすべての工程で活用される知識ですので、スキルアップを目指すエンジニアの方は一緒に学んでいきましょう。

# オブジェクト指向プログラミング(OOP)

## 構造化プログラミングの限界（OOPが生まれる前）

OOPの誕生前では、構造化言語を用いて機能中心設計でシステムを開発していました。

構造化プログラミングは、処理を手続きとして順番に記述するスタイルで実装します。

また、機能中心設計では、機能ごとに独立して手続き的に処理を記述していきます。

そのため、構造化言語と機能中心設計を合わせると、

「プログラムの各所で似たようなデータやデータを扱う処理が重複している状態」になります(関数やサブルーチンによって処理の再利用の仕組みはあったが不十分)。

当時、ソフトウェアのライフサイクルが長期化したことによって、機能追加や仕様変更、バグ修正といった保守の重要性が高まりました。

しかし、このようなシステムの保守を行うとき、一連の処理の一部を変更するとその後の処理全体に影響を与えたり、重複したコードの変更の漏れが発生するなど、簡単には手を加えることができないという課題が発生しました。

また、グルーバル変数の問題もあり、意図しない副作用(≒変数の書き換え)が発生しやすい状態にありました。

(ex. 銀行システムで振り込み・残高紹介・送金処理の全てで口座番号というデータを持つ。仕様変更で口座番号を10桁→16桁にした時、全ての処理で変更が必要。)

## オブジェクト指向の誕生と基本思想

オブジェクト指向は、こうした課題を解決するために生まれた考え方です。その本質は「モノ（オブジェクト）中心」にソフトウェアを設計するという点にあります。

現実世界では、人やモノが「データ（状態）」と「行動（振る舞い）」を一体として持っています。オブジェクト指向では、この考えをそのままソフトウェアに取り入れ、データと処理を一つのまとまり（クラス）として定義します。

オブジェクト指向の基本的な要素は以下のとおりです。

- **カプセル化**：データと処理をクラスにまとめて外部から隠すことで、影響範囲を局所化する
- **継承**：既存のクラスを拡張して新しいクラスを作ることで、再利用性を高める
- **ポリモーフィズム（多態性）**：同じインターフェースで異なる処理を実行できるようにすることで、柔軟性を高める
- **抽象化**：複雑な実装を隠し、必要なインターフェースだけを提供することで、設計の明確化と実装の独立性を高める

こうした特徴により、OOPはソフトウェアの保守性、再利用性、拡張性を大幅に向上させました。

## コード例：構造化 vs オブジェクト指向

ここでは、先ほどの銀行システムの例を実装していきます。

【構造化プログラミングの例】

```python
# グローバル変数でデータを管理
account_number = "1234567890"
balance = 100000

def transfer():
    if len(account_number) == 10:
        print(f"{account_number} から送金処理を行います。")
    else:
        print("口座番号が無効です")

def check_balance():
	if len(account_number) == 10:# バリデーションロジックの重複
      print(f"{account_number} の残高は {balance} 円です。")

def send_money():
    print(f"{account_number} から他の口座に送金します。")
  
  
transfer()
check_balance()
send_money()
```

- 桁数のバリデーションが関数ごとに重複している
- `account_number`がグローバルに共有され、意図しない変更が起きる可能性がある
    - 型チェックがなく、マイナスの残高のような不正な値が混入する可能性がある
- 口座番号の桁数が「10桁」→「16桁」になったとき、**全関数を探して修正しないといけない**（漏れのリスク）

【オブジェクト指向の例】

(そこまで綺麗なコードではありませんがご容赦ください)

```python
# 値オブジェクト：AccountNumber
class AccountNumber:
    def __init__(self, number: str):
        if not self._is_valid(number):
            raise ValueError("口座番号は16桁でなければなりません")
        self._number = number
		
		# クラス内にバリデーションロジックを持つ
    def _is_valid(self, number: str) -> bool:
        return len(number) == 16 and number.isdigit()

# 値オブジェクト: Balance
class Balance:
    def __init__(self, amount: int):
        if amount < 0:
            raise ValueError("残高は負の値にはできません")
        self._amount = amount

    @property
    def amount(self):
        return self._amount

    def decrease(self, value: int):
        if value > self._amount:
            raise ValueError("残高不足です")
        self._amount -= value
				# 新たなインスタンスを返しても良い
				# return Balance(self._amount)
				
    def increase(self, value: int):
        if value < 0:
            raise ValueError("負の金額は加算できません")
        self._amount += value

    def __str__(self):
        return f"{self._amount} 円"

# エンティティ: BankAccount
class BankAccount:
		# 独自クラスを型として定義できる
    def __init__(self, account_number: AccountNumber, balance: Balance):
        self.account_number = account_number
        self.balance = balance

    def transfer(self, amount: int):
        self.balance.decrease(amount)
        print(f"{self.account_number.branch_code} 支店の口座 {self.account_number.account_id} から {amount} 円を送金しました。")

    def check_balance(self):
        print(f"{self.account_number} の残高は {self.balance} です。")

    def send_money(self, amount: int):
        self.balance.decrease(amount)
        print(f"{self.account_number} から他口座へ {amount} 円を送金しました。")

# 実行
acc_num = AccountNumber("1011234567")
bal = Balance(100000)
account = BankAccount(acc_num, bal)

account.transfer(5000)
account.check_balance()
account.send_money(10000)
```

- バリデーションが**値オブジェクトの中に集約**
- `Balance` で残高の整合性・不変条件を担保（**負の残高防止、加減のルールを制御**）
- 全体として副作用のリスクが少なく、**拡張や変更に強い構造**
- 型チェックで堅牢なプログラムになる
    - OOP以前では厳格な型チェックをできる機能がなかった

## OOPがもたらした周辺技術

オブジェクト指向が普及するにつれ、それに適応した技術やツールも多く登場しました。代表的なものには以下があります。

- パッケージ・モジュール：機能ごとのグルーピングと責務の明確化を助ける
- 名前空間：同じ名前のクラスや関数が衝突しないようにする仕組み
- 例外処理：予期しないエラーに柔軟に対応できる
- ガベージコレクション：自動メモリ解放

これらの技術は現代のソフトウェア開発において欠かせない存在となっています。

このように、オブジェクト指向は単なるプログラミングスタイルではなく、ソフトウェア開発全体の在り方を変える力を持つ技術です。設計から保守に至るまで、あらゆる場面でその恩恵を受けることができます。
駆け出しエンジニアであっても、少しずつ意識して取り入れていくことで、より良いコード・より良い開発が実現できるはずです。
一緒に少しずつ慣れていきましょう。

# 再利用可能な部品群

## はじめに

ソフトウェア開発の現場では、「すべてを一から書く」ということはほとんどありません。なぜなら、すでに存在する“部品”や“設計知”を再利用する方が、圧倒的に効率的で、品質も高くなるからです。

オブジェクト指向（OOP）は、この「再利用性の高い部品化」を実現したパラダイムです。本章では、OOPと再利用性の関係性を軸に、ソフトウェア開発を支える設計パターンの思想までを掘り下げていきます。

## OOPが再利用性をもたらした理由

上記で解説した通り、OOPは「データ」と「そのデータを操作する処理」をひとまとまりのオブジェクトとして表現します。この“ひとまとまり”が、部品としての再利用を可能にしています。

クラスは部品の設計図に相当し、生成したインスタンスオブジェクトを複製可能な部品として扱います。さらに継承やポリモーフィズム（多態性）により、既存のクラスの振る舞いを拡張・変更できる柔軟性も備えています。これらの性質が、個々の部品の独立性と、影響範囲の局所化を実現し、再利用を容易にしています。

実際の現場では、フレームワークやライブラリ、UIコンポーネントなどが“部品”として活用されています。これらは「アプリケーションの半完成品」ともいえる存在で、開発者はそこに要件を肉付けしていくだけで、高品質なアプリケーションを短期間で構築できます。

この仕組みは、メールのテンプレートに例えるとわかりやすいでしょう。挨拶・本文・締めという“型”があり、あとは必要な部分に文言を差し込むだけであり、誰が使っても一定の品質が保たれる仕組みです。

## 「パターン」の誕生と意義

OOPの登場により再利用可能な部品が生まれましたが、それを正しく使うこと、よりよい設計を実現することは簡単ではありません。そこで生まれたのが「デザインパターン」です。

デザインパターンとは、優れた設計の共通点を抽出し、名前をつけ、文書化した“再利用可能な設計のテンプレート”です。これにより、同じ問題に対して同じような解決方法を取れるようになり、設計の再利用性と柔軟性が大幅に向上しました。

OOPとパターンは相互に発展してきました。

1. OOPによって、再利用可能な部品群が生まれた
2. それらの中から、優れた設計が抽出・命名され、パターン化された
3. その知見をもとに、新たな部品や設計が生まれた

2と３を行き来した試行錯誤の中で今日のデザインパターンが誕生しました。

デザインパターンは、OOPの力を引き出すための“設計知”の集積といえるでしょう。

## その他パターン

再利用の発想は、単なるオブジェクトやクラスの設計にとどまりません。ソフトウェア開発のあらゆるレイヤーに“パターン”は存在しています。(ここで言うパターンとは、優れたアイデアを命名して文書化したものとします。)

- **データ構造パターン**：リスト、スタック、キューなど
- **アルゴリズムパターン**：ソート、探索、分割統治など
- **アナリシスパターン**：業務分析や要件定義の知見の再利用
- **アーキテクチャパターン**：MVC、クリーンアーキテクチャなどの構造化手法
- **言語イディオム**：言語特有の洗練された書き方（Pythonic, idiomatic Kotlinなど）
- **プロセスパターン**：XP、スクラム、Gitフローなどの開発手法
- **アンチパターン**：ありがちな失敗例とその回避策

こうしたパターンはすべて、人類がソフトウェア開発の中で蓄積してきた知恵の結晶です。設計や実装だけでなく、思考や意思決定の“型”として、プログラミング文化の基盤を形作っています。

OOPは、再利用可能な部品化を実現するための強力な設計手法です。その上に生まれた「パターン」は、設計知識の共有インフラとして、時代を超えて活用され続けています。

ソフトウェア開発は、もはや「一人の天才による芸術」ではありません。数十年にわたって洗練されてきた“型”と“知見”を活かしながら進化する、集団的で文化的な営みと言えます。

# 汎用分析手法

オブジェクト指向の考え方の根底には、私たちが日常で自然に行っている「ものの見方」や「整理のしかた」があります。

たとえば、「同じ種類のものをひとまとめにする」「役割ごとに作業を分担する」といった考え方は、学校でも職場でも使われているはずです。

OOPは、そうした思考法をプログラムに翻訳する手法でもあります。

ここでは特に、

- **集合論的な見方**（似たものをまとめて整理する）
- **役割分担的な見方**（誰が何をするかを明確にする）

という2つの視点から、OOPの本質に迫ってみましょう。

## 集合論的なものの見方

まずは「似たものをまとめる」＝**集合論的な視点**です。

### クラスとインスタンスの関係

集合論では、似た特徴を持つものを一つの「集合」としてまとめます。

たとえば「哺乳類」や「果物」といった分類がその典型です。

OOPでも同様に、「クラス」という型（設計図）と、「インスタンス」という個々の具体的なもの（実体）で世界を表現します。

- クラス = 集合
- インスタンス = 集合に属する要素

例：会社組織

```
全体集合：社員（30名）
　├─ 部分集合：営業部（10名）
　├─ 部分集合：経理部（3名）
　└─ 部分集合：人事部（2名） … など
```

この構造は、そのまま OOPの継承や分類の発想に対応します。

```java
class Employee { ... }
class Sales extends Employee { ... }
class Accounting extends Employee { ... }
```

### 汎化（Generalization）＝共通点を抽出してまとめる

営業も経理も「社員」であることに変わりはありません。

共通点（例えば名前や社員番号）を `Employee` にまとめることで、**再利用性の高い設計**ができます。

これは集合論でいう「上位集合・下位集合（包含関係）」の考え方そのものです。

## 役割とメッセージパッシング

次に、「誰が何をするか」という**役割ベースの見方**です。

OOPでは、すべてのオブジェクト（＝登場人物）は、自分の責任をもち、他のオブジェクトと**メッセージのやりとり**で連携します。

### 例：レストランでの注文

```
客 → ウェイトレス → シェフ → 料理
```

この一連の流れは、それぞれの**役割の分担**と**メッセージの受け渡し**で成り立っています。

OOPに落とし込むと、こんな風になります：

```java
customer.order("オムライス", waitress);
waitress.relayOrderTo(chef);
chef.cook("オムライス");
```

ここで重要なのは、**各自が「自分の仕事」だけを知っていればいい**ということです。

他の内部の動作には依存しないので、変更に強く、保守しやすいコードになります。

## 集合論 × 役割分担 ＝ 業務の抽象化

最後に、この2つの視点を組み合わせて、**現実の業務をOOP的に捉える**方法を見てみましょう。

- 現実の例：
    - 加藤さん（営業部）が佐藤さん（経理部）に経費申請を依頼する

- OOP的に抽象化すると：
    - `SalesEmployee` が `Accounting` に `requestExpense` を送る

```
SalesEmployee kato = new SalesEmployee("加藤");
Accounting satou = new Accounting("佐藤");
kato.requestExpense(satou, 10000);
```

ここには、

- 「社員という集合」の中に属する個々の人たち（集合論的視点）
- 「申請する・処理する」という役割分担（役割視点）

という、OOPの核となる考え方が自然に組み込まれています。

この章をまとめると、

- OOPの背後には、**現実世界の捉え方そのもの**がある
- 特に、「集合論的な分類」と「役割分担」という2つの視点が重要
    - これは現実世界の分析にも有効
- これらを使うことで、**複雑な現実の仕組みを抽象化し、設計に落とし込むことができる**

ということです。

# 上流工程

私たちはプログラムを書く前に、必ず「何を作るのか」「なぜ作るのか」を考える必要があります。これは「上流工程」と呼ばれる、ソフトウェア開発のスタート地点です。

多くの人が「オブジェクト指向って、クラスとか継承とかコードの話でしょ？」と思っています。でも実は、オブジェクト指向の考え方はもっと広く、**ソフトウェア開発の最上流＝業務の理解や要件定義のフェーズでも役に立つ**ものなのです。

## オブジェクト指向は、現実をモデリングする考え方

汎用分析手法で示した通り、オブジェクト指向の考えを活用すると、現実世界の分析とそれのプログラムでの表現がしやすくなります。

オブジェクト指向の根底にあるのは、「現実世界をうまく分解して、ソフトウェアとして再構築する」ことであり、**目の前の現実を“モデリング”する力を秘めています**。

たとえば、給与システムを作るとき。「部門」「従業員」「給与明細」などの“もの”と、それぞれの“役割”や“やりとり”を整理しますよね。これはまさに、オブジェクト指向の視点そのものです。

## 上流工程にもオブジェクト指向の視点を

では、ソフトウェアを作る前のステップを見てみましょう。

### 1. 業務分析：現実世界を観察・整理する

- まずは現場を知ることから始まる
- どんな部署があって、誰が、どんな流れで仕事をしているのかを把握
    - 「登場人物（オブジェクト）」と「やり取り（メッセージ）」を捉える
- UMLなどで図示し、ステークホルダーと議論

### 2. 要件定義：コンピュータに任せる範囲を決める

- 分析した業務の中から、コンピュータが得意なことを見つけて任せる
    - 決まりきった計算作業
    - 大量のデータの記録と検索
- 人間とコンピュータの“役割分担”をはっきりさせることが目的

### 3. 設計：ソフトウェアの骨組みを考える

- 技術的な制約（使う言語やサーバー、OSなど）を考慮し、どんな構造で、どんな機能をもったシステムにするのかを決める
- ここで初めて、「クラス」や「インターフェース」といったOOP的な設計が登場する

## UML：OOPの考えを図で表すツール

(UMLはこちらの動画がとてもわかりやすいです。

https://youtube.com/playlist?list=PLYf0TVKgD6wul4x7wQ_YR1ADIbQjiraAK&si=bzzRkbde8B3WRC7D

また、以前書いた記事ではおすすめの書籍を紹介しているので、よろしければご覧ください。

https://qiita.com/ishikawahijiri/items/2989b4f478fbd6336876

)

(UMLの記事を書いたので、よろしければご覧ください

https://qiita.com/ishikawahijiri/items/77b960cea1e37b7a7d17

)

OOPの“モデリング力”を活かすために生まれたのがUML（統一モデリング言語）です。
UMLは、業務やシステムの構造を「図で可視化」できるツール。

たとえば：

- ユースケース図：ユーザーが何をするかを整理
- クラス図：システムの部品（クラス）と関係性を整理
- シーケンス図：オブジェクト間のやり取りの流れを整理

UMLは、エンジニアだけでなく、業務担当者との**共通言語**としても役立ちます。

## 上流工程からOOP的に考えるメリット

OOPの視点で業務や要件を整理すると、たくさんのメリットがあります。

- **責任の分離**が明確になる
    
    → 誰が何を担当しているかが見えやすくなる
    
- **変更に強い構造**が作れる
    
    → 「ここだけ変えたい」が実現しやすくなる
    
- **後工程がスムーズ**になる
    
    → 分析・設計の時点で“オブジェクト”が明確なら、実装も自然に組み上がる
    

オブジェクト指向は「書き方」ではなく「考え方」であり、設計段階だけでなく上流工程でも非常に役立ちます。現実をよく観察し、適切に分解して、筋道立てて構造を作る、オブジェクト指向はそんな思考の技術でもあります。

これまで解説したように、上流工程でオブジェクトを中心としたモデリングをすることで、下流でのOOPへのスムーズな移行を実現します。

# 反復開発手法

最後に、現在、広く受け入れられているアジャイル開発などの反復開発手法を解説します。

(僕がエンジニアとして日が浅く、あまり知識がないため歴史的経緯や各種法を簡単に説明するにとどめます。)

## 歴史的経緯

オブジェクト指向とアジャイル開発は、一見すると異なる領域に見えるかもしれません。しかし、歴史的・技術的な背景をたどると、両者は深い関係性を持っています。

かつてソフトウェア開発の現場では、開発環境やハードウェア性能が現在ほど整っておらず、コードのビルドや実行に一晩かかるということもざらだったようです。

変更のコストが非常に高かったため、開発プロジェクトでは初期段階で要件と仕様を厳密に定め、後からの変更を最小限に抑えるウォーターフォール型の開発手法が主流でした。

しかし、近年では開発ツールやハードウェアの進化により、ソフトウェアの変更が容易になり、柔軟な対応が可能になってきました。オブジェクト指向プログラミング（OOP）の特性を活かしたテストツールや設計技法の発展により、アジャイル的な開発スタイルが現実的な選択肢となったのです。

たとえば、JUnitやxUnitといったテストフレームワークは、OOPの仕組みを活用して設計されており、単体テストを容易にしました。リファクタリングにおいても、メソッドの抽出やクラスの分割といった改善手法は、オブジェクト指向の構造を前提としています。

また、アジャイル開発の代表的手法であるXP（エクストリーム・プログラミング）やTDD（テスト駆動開発）、リファクタリングといった概念は、いずれもオブジェクト指向の実践者たちによって提唱・発展されてきました。彼らはSmalltalkやJavaなどのオブジェクト指向言語の開発に深く関わり、ソフトウェア設計やデザインパターンといった分野でも大きな影響を与えています。

このように、技術的背景や開発者コミュニティの重なりを通じて、オブジェクト指向とアジャイル開発は互いに密接な関係を築いてきました。そのため、オブジェクト指向を学ぶ文脈でアジャイルが登場するのは自然な流れであり、現代のソフトウェア開発を理解する上でも両者を並行して捉えることが有効です。

## 開発手法の重要性と反復型の登場

ソフトウェア開発は、クライアント、営業、エンジニアなど異なる立場の人々が関わる**共同作業**である。そのため、**単なる技術力や知識だけでなく、「どう開発を進めるか」というプロセス設計が極めて重要**になります。

その中で、「反復開発（イテレーション）」は、従来のウォーターフォール型に代わる**柔軟で現実的な開発アプローチ**として注目されてきました。

### ウォーターフォール開発の特徴と課題

ウォーターフォール開発は、「要件定義 → 設計 → 実装 → テスト」といった工程を**一方向に順番に進める**手法です。

- **メリット**
    - 文書中心で進捗・責任範囲が明確
    - 契約や請負型開発に向いている
    - 先述の通り、ハードウェアの性能が低かった頃は適していた
- **デメリット**
    - 初期の要件定義のミスが後半で重大な問題になる
    - 開発途中での仕様変更に弱い（コスト・手戻りが大きい）
    - 現在はコードの変更コストが昔より低いので時代に合わないという考えもある

### 反復開発（イテレーション）：柔軟に作りながら考える

反復開発は、設計からテストまでの工程を短いサイクル（イテレーション）で何度も繰り返す手法であり、中間リリースで「動くもの」を見せてフィードバックを得ることで、より良いものに近づけていきます。

- **メリット**
    - ユーザーの要望の変化に柔軟に対応できる
    - 早期に動くプロトタイプが得られ、技術的課題も早期に発見できる
- **デメリット**
    - 各機能で要件定義、設計などフェーズが存在し、プロジェクトの管理が複雑になる

### XP（エクストリーム・プログラミング）：コード重視の実践型反復手法

XPは、反復開発をベースに、「**実装中心・フィードバック重視**」の文化を持つそれ以前とは全く異なる開発手法であり、ドキュメントよりも実際に動くコードを重視する。

- 4つの価値観
    - **コミュニケーション**：対話重視のチーム運営
    - **フィードバック**：早期確認と即時改善
    - **シンプルさ**：最低限の設計で始める
    - **勇気**：状況に応じて設計や実装を見直す
- **主なプラクティス**
    - ペアプログラミング
    - 小さなリリース
    - テスト駆動開発（TDD）
    - リファクタリング
    - 継続的インテグレーション（CI）　など

### スクラム：チーム主導の反復開発

スクラムは、**自律的なチームと役割分担**を重視する反復型の開発フレームワークであり、ラグビーのスクラムのように、少人数のチームが連携しながら開発を進める手法です。

- **主な役割**
    - **プロダクトオーナー**：開発内容（バックログ）の優先順位を決める
    - **開発チーム**：自己組織化されたクロスファンクショナルなメンバー
    - **スクラムマスター**：スクラムの推進・障害除去をサポート
- ソフトウェア開発に限らず、複雑な製品の開発・保守運用をチームで行う際のフレームワークを目指したもの

### アジャイル開発：価値観としての反復

2001年の「アジャイルソフトウェア開発宣言」では、次の4つの価値が掲げられています。

1. **プロセスやツールより、個人と対話を重視する**
2. **包括的な文書より、動くソフトウェアを重視する**
3. **契約交渉より、顧客との協調を重視する**
4. **計画に従うより、変化への対応を重視する**

- アジャイルを支える技術と文化
    - TDD（テスト駆動開発）
        - 先にテストを書き、動くコードでテストを通す
        - 設計のミスを早期に発見しやすく、コードの独立性も向上
    - リファクタリング
        - 動作は変えずに内部構造を整理し、保守性を高める
        - 設計の健全性を保ち、長期的な品質を支える
    - CI（継続的インテグレーション）
        - ビルドやテストを自動化し、常に統合可能な状態を維持
        - エラーの早期発見とチームの一体感につながる

### 手法の視点と活用のまとめ

- **ウォーターフォール**：管理者視点。文書・契約・事前計画重視
- **XP**：プログラマ視点。コード・改善・技術力重視
- スクラム：チーム視点。協力・自律性・継続的改善重視

アジャイル時代においては、「万能な手法」は存在せず、プロジェクトやチームに合ったやり方を柔軟に組み合わせることが重要であるとされています。

# まとめ

ここまでお付き合いしていただいた読者の皆様、誠にありがとうございます。

オブジェクト指向は複雑かつ、広い概念であり、初心者にとっては難解だと思います。

しかし、この記事のように細分化すれば各分野はそこまで難しいものではなく、僕たちのエンジニアを強力にサポートするような考えや技術であるということがご理解いただけたかと思います。

僕も全てを理解したわけではなく、これからの記事でそれぞれを深掘っていく時に深く学びを得られるように頑張っていくつもりです。

エンジニアの皆様、特に、僕と同じく駆け出しの方にとって有益な情報をお届けしてけるよう、精進してまいります。

次回はUMLについて解説する記事を書こうと思っています。
また、デザインパターンもしっかりと勉強する予定です。

(もしくは、僕は業務でPLM(製造業効率化)をすることになったため、その周辺知識や製造業DXについての記事も書く予定です。)

内容の誤りや質問などございましたら、コメントにて申し付けください。

このアカウントでは、週に一本のペースで投稿しております。
それでは皆様、また来週。