新人の為のペアプロ入門



---
## タイトル: JavaとC#の問題を解く場合のペアプロ入門
---

ペアプロ（ペアプログラミング）は、**2人1組で1つのコンピュータを使い、共同でプログラムを開発する方法**です。具体的には、1人がコードを書く「**ドライバー**」としてキーボードを操作し、もう1人が「**ナビゲーター**」としてコードの確認や設計のアドバイスを行います。

### ペアプロの特徴
- **役割の交代**: ドライバーとナビゲーターの役割は一定時間ごとに交代します。これにより、両方の人がコードを書く経験をしつつ、相手の視点からアドバイスを受けることができます。
- **リアルタイムのフィードバック**: ナビゲーターがコードのミスや改善点に気づいたら、その場で指摘し、修正や改善をリアルタイムで行います。
- **協力して問題を解決**: 1人で考えに行き詰まったときでも、ペアで取り組むことでアイデアや解決策を見つけやすくなります。

### ペアプロの利点
- **スキル向上**: 他の人の考え方や視点に触れることで、自分のスキルや知識の幅を広げることができます。
- **品質向上**: ナビゲーターが常にコードをチェックしているため、バグやロジックのミスを早い段階で発見できます。
- **コミュニケーションの強化**: 開発者同士のコミュニケーションスキルが向上し、チームでの仕事がしやすくなります。

### ペアプロが効果的な状況
- **新人教育**: 経験の少ない開発者が先輩とペアを組むことで、実際の開発現場での学びが得られやすくなります。
- **複雑な問題に取り組むとき**: 複雑なアルゴリズムや大規模な設計に対して、2人で頭を突き合わせて解決することが有効です。

ペアプロは単なる共同作業ではなく、**協力して問題を解決し、互いに学び合う**開発手法として広く使われています。

---
## ルール
---

### 1. **役割分担を明確にする**
   - **ドライバー（コードを書く人）** と **ナビゲーター（サポートやアドバイスをする人）** の役割を明確にし、適切に交代しながら進めると良いです。
   - ドライバーは実際に手を動かしてコードを書く役割で、ナビゲーターは設計や論理的なアプローチを考えるサポート役として機能します。

### 2. **設計を一緒に考える**
   - 問題に取り組む前に、ペアでクラスの設計について一緒に話し合います。どのようなフィールドやメソッドが必要かを整理し、全体の流れを把握する時間を持ちます。
   - 「どのメソッドから始めるべきか」「フィールドは何を持たせるべきか」などを一緒に考え、共通の理解を持たせることが重要です。

### 3. **ドライバーがコードを書く際、ナビゲーターはガイドを提供する**
   - ドライバーがコードを書いている間、ナビゲーターは全体像を見ながら、エラーや設計の問題に気づいた場合に指摘したり、次に書くべき部分を提案します。
   - 「その部分はこう書いてみたらどうかな？」など、具体的なアドバイスを与えることで、スムーズに進められます。

### 4. **定期的に交代する**
   - 例えば、フィールドの定義が終わったら、ドライバーとナビゲーターを交代し、もう一方がメソッドを実装するなど、役割を定期的に入れ替えることで、両方が理解を深められます。

### 5. **振り返りの時間を持つ**
   - 一通り書き終えたら、ペアで書いたコードを見直し、設計やロジックに問題がないか確認する時間を設けます。
   - 「ここは別のアプローチもできたかも」「エラーハンドリングはこうした方がいいかも」など、改善点をお互いに話し合うと良いです。

### 6. **サポートの提供**
   - 未経験者がいる場合、適宜サポートを提供し、分からない部分があれば質問しやすい雰囲気を作りましょう。

---
## ペアプロでの時間配分例（約2時間）
---

1. **設計の話し合い（15～20分）** 
   - フィールドやメソッドの構造をペアで一緒に考え、全体の流れを理解します。
   - 「どの部分から手をつけるべきか」「どういった例外処理が必要か」など、設計の指針を立てる時間です。

2. **コーディング（1時間）**  
   - ドライバーとナビゲーターの役割を決め、実際にコードを書いていきます。
   - 約30分ごとにドライバーとナビゲーターを交代しながら進めると良いでしょう。
   - 各メソッドやクラスの実装を区切りごとに進めることで、バランスよく学習できます。

3. **テストと確認（20～25分）**  
   - 実装が完了した後、ペアでコードをレビューし、動作テストを行います。
   - エラー処理や例外処理が正しく動いているか、期待通りに本のデータが管理できるかを確認します。

4. **振り返りと改善（15分）**  
   - コード全体を見直し、どこに改善点があるか、次回どのように進めたら良いかを話し合います。
   - 振り返りの時間を設けることで、次に生かす学びを得ることができます。

### 時間を決めるメリット
- **効率の向上**: 時間を区切ることで、目的に向かって効率よく進められます。
- **進行の見通しが立てやすい**: どのフェーズにどれくらいの時間がかかるかが事前にわかっていると、無駄に時間がかかるのを防げます。
- **適切な役割交代**: 時間を区切ることで、ドライバーとナビゲーターの役割がうまく回り、両方がバランスよく学べます。

時間配分を決めることで、スムーズに進行し、成果を得やすくなります。


問題：個人用の読書管理システムを作成してください。このシステムは、ユーザーが読んだ本や読みたい本を記録し、読書の進捗を追跡するシステムです。以下の要件を満たすようにプログラムを作成してください。

1. `Book` クラスを作成し、以下のフィールドとメソッドを持たせてください：

   - フィールド:
     - タイトル(title): String 型
     - 著者(author): String 型
     - ページ数(pages): int 型
     - ジャンル(genre): String 型
     - 読了日(completionDate): String 型（未読の場合は null）
     - 評価(rating): int 型（1-5 の範囲、未評価の場合は 0）
   - コンストラクタ:
     - タイトル、著者、ページ数、ジャンルを初期化するコンストラクタ
   - メソッド:
     - `getBookInfo()`: 本の情報を文字列で返す
     - `markAsRead(String date)`: 本を読了済みにし、読了日を設定する
     - `setRating(int rating)`: 本の評価を設定する（1-5 の範囲外の場合は例外をスロー）
     - `isRead()`: 本が読了済みかどうかを返す

以下に、この問題を解く際のヒントをいくつか挙げます。

### 1\. **クラスの設計**

- クラスを設計するときは、まず **フィールド（変数）** と **メソッド** の関係を整理しましょう。今回の `Book` クラスには、**本に関する情報**（タイトル、著者、ページ数など）を格納するフィールドが必要です。
- **コンストラクタ** では、クラスのフィールドを初期化します。必要な情報（タイトル、著者、ページ数、ジャンル）はコンストラクタの引数として受け取ると良いでしょう。
```mermaid
classDiagram
    class Book {
        - String title
        - String author
        - int pages
        - String genre
        - String completionDate
        - int rating
        + Book(String title, String author, int pages, String genre)
        + String getBookInfo()
        + void markAsRead(String date)
        + void setRating(int rating)
        + boolean isRead()
    }
```

### 2\. **メソッドの設計**

- `getBookInfo` メソッドでは、**本の情報を一つの文字列** として返します。例えば、タイトル、著者、ページ数、読了日、評価などの情報を改行で区切って表示するのが分かりやすい方法です。
- `markAsRead` メソッドは、本が読了済みかどうかを記録する役割です。**読了日を設定** することで、未読と区別できます。
- `setRating` メソッドでは、評価が **1 ～ 5 の範囲** にあるかをチェックし、範囲外の場合には **例外処理** を用いてエラーメッセージを表示することが求められます。
- `isRead` メソッドでは、**completionDate（読了日）** が設定されているかどうかで、読了済みかどうかを判断します。

### 3\. **例外処理**

- 評価（rating）を設定する際には、 **1 ～ 5 以外の値を受け取らないようにする** 必要があります。そのために `IllegalArgumentException` を使い、間違った入力に対して適切なエラーメッセージを表示しましょう。

## **解答**

```java
public class Book {
    // フィールド
    private String title;
    private String author;
    private int pages;
    private String genre;
    private String completionDate; // 未読の場合はnull
    private int rating; // 1-5の範囲、未評価の場合は0

    // コンストラクタ
    public Book(String title, String author, int pages, String genre) {
        this.title = title;
        this.author = author;
        this.pages = pages;
        this.genre = genre;
        this.completionDate = null; // 初期状態では未読
        this.rating = 0; // 初期状態では未評価
    }

    // 本の情報を取得するメソッド
    public String getBookInfo() {
        String status = (completionDate == null) ? "未読" : "読了";
        return "タイトル: " + title + "\n" +
               "著者: " + author + "\n" +
               "ページ数: " + pages + "\n" +
               "ジャンル: " + genre + "\n" +
               "読了日: " + (completionDate == null ? "未読" : completionDate) + "\n" +
               "評価: " + (rating == 0 ? "未評価" : rating) + "\n" +
               "ステータス: " + status;
    }

    // 本を読了済みにし、読了日を設定するメソッド
    public void markAsRead(String date) {
        this.completionDate = date;
    }

    // 評価を設定するメソッド（1-5の範囲外の場合は例外をスロー）
    public void setRating(int rating) {
        if (rating < 1 || rating > 5) {
            throw new IllegalArgumentException("評価は1から5の範囲で設定してください。");
        }
        this.rating = rating;
    }

    // 本が読了済みかどうかを返すメソッド
    public boolean isRead() {
        return completionDate != null;
    }

    // メインメソッドでのテスト例
    public static void main(String[] args) {
        // 新しい本を作成
        Book book = new Book("吾輩は猫である", "夏目漱石", 250, "文学");

        // 本の情報を表示
        System.out.println(book.getBookInfo());

        // 本を読了済みにする
        book.markAsRead("2024-08-20");
        System.out.println("\n読了後の情報:");
        System.out.println(book.getBookInfo());

        // 評価を設定
        book.setRating(5);
        System.out.println("\n評価後の情報:");
        System.out.println(book.getBookInfo());
    }
}
```

### 説明

- `Book` クラスには、タイトル、著者、ページ数、ジャンル、読了日、評価を管理するためのフィールドがあります。
- コンストラクタでは、本のタイトル、著者、ページ数、ジャンルを設定します。読了日は最初は `null`、評価は最初は `0` に設定されます。
- `getBookInfo` メソッドは、本の詳細情報を返します。読了していない場合、読了日には「未読」と表示されます。
- `markAsRead` メソッドは、本を読了した際に読了日を設定します。
- `setRating` メソッドは、本の評価を 1-5 の範囲で設定します。範囲外の場合は `IllegalArgumentException` がスローされます。
- `isRead` メソッドは、本が読了済みかどうかを `boolean` で返します。

このコードを使って、個人用の読書管理システムの基本的な機能を構築できます。