基礎から学ぶC#入門 90日コース | 継承・抽象化・インターフェース - Day 50:第5章総合演習

C# 90日で身につけるC#
スポンサーリンク
スポンサーリンク

Day 50 のゴールと全体像

Day 50 は 第5章の総まとめとして、 複数のクラスを連携させて動く 簡易注文システムを作ります。

登場するクラスは次の4つです。

  • Customer(顧客)
  • Product(商品)
  • Order(注文)
  • OrderItem(注文内の商品)

ここまで学んできた、

  • 継承
  • 抽象化
  • インターフェース
  • 多態性
  • 依存関係
  • 状態管理

といったオブジェクト指向の考え方を、 「注文システム」という実践的なテーマに落とし込んでいきます。

雑誌記事を読むような柔らかいトーンで、 ステップバイステップで設計していきます。

システム全体の構造をイメージする

まずは、4つのクラスがどのように関係するかを言葉で整理します。

Customer(顧客)

  • 顧客ID
  • 名前
  • メールアドレス
  • 注文を作る

Product(商品)

  • 商品ID
  • 商品名
  • 価格

OrderItem(注文内の商品)

  • 商品
  • 数量
  • 小計(価格 × 数量)

Order(注文)

  • 注文ID
  • 顧客
  • 注文日時
  • 注文アイテムの一覧
  • 合計金額

この4つが連携して、 ひとつの注文を表現します。

Step 1:Product(商品)クラスを作る

商品はシンプルなデータ構造です。

using System;

// 商品クラス
class Product
{
    public int Id { get; }
    public string Name { get; }
    public decimal Price { get; }

    public Product(int id, string name, decimal price)
    {
        Id = id;
        Name = name;
        Price = price;
    }

    public void ShowInfo()
    {
        Console.WriteLine($"商品ID: {Id}, 名前: {Name}, 価格: {Price}円");
    }
}
C#

ポイント:

  • 商品は「値を持つだけ」のシンプルなクラス
  • record を使ってもよい場面ですが、今回は学習のため class で作成

Step 2:Customer(顧客)クラスを作る

顧客は注文を作る役割を持ちます。

using System;

class Customer
{
    public int Id { get; }
    public string Name { get; }
    public string Email { get; }

    public Customer(int id, string name, string email)
    {
        Id = id;
        Name = name;
        Email = email;
    }

    public void ShowInfo()
    {
        Console.WriteLine($"顧客ID: {Id}, 名前: {Name}, メール: {Email}");
    }
}
C#

ポイント:

  • 顧客は「注文を作る側」
  • 今回は注文作成処理は Order 側に任せます

Step 3:OrderItem(注文アイテム)を作る

注文内の商品と数量を表すクラスです。

using System;

// 注文アイテム
class OrderItem
{
    public Product Product { get; }
    public int Quantity { get; }

    public OrderItem(Product product, int quantity)
    {
        Product = product;
        Quantity = quantity;
    }

    // 小計(価格 × 数量)
    public decimal GetSubtotal()
    {
        return Product.Price * Quantity;
    }

    public void ShowInfo()
    {
        Console.WriteLine($"{Product.Name} × {Quantity} = {GetSubtotal()}円");
    }
}
C#

ポイント:

  • 商品と数量をセットで扱う
  • 小計計算は OrderItem の責務

Step 4:Order(注文)クラスを作る

注文は複数の OrderItem を持ちます。

using System;
using System.Collections.Generic;

// 注文クラス
class Order
{
    public int Id { get; }
    public Customer Customer { get; }
    public DateTime OrderDate { get; }
    private readonly List<OrderItem> items = new List<OrderItem>();

    public Order(int id, Customer customer)
    {
        Id = id;
        Customer = customer;
        OrderDate = DateTime.Now;
    }

    // 注文に商品を追加する
    public void AddItem(Product product, int quantity)
    {
        items.Add(new OrderItem(product, quantity));
        Console.WriteLine($"{product.Name} を {quantity} 個追加しました。");
    }

    // 合計金額
    public decimal GetTotal()
    {
        decimal total = 0;
        foreach (var item in items)
        {
            total += item.GetSubtotal();
        }
        return total;
    }

    // 注文情報を表示する
    public void ShowInfo()
    {
        Console.WriteLine("=== 注文情報 ===");
        Console.WriteLine($"注文ID: {Id}");
        Console.WriteLine($"顧客: {Customer.Name}");
        Console.WriteLine($"注文日時: {OrderDate}");
        Console.WriteLine("--- 注文アイテム ---");

        foreach (var item in items)
        {
            item.ShowInfo();
        }

        Console.WriteLine($"合計金額: {GetTotal()}円");
    }
}
C#

ポイント:

  • 注文は「顧客」「注文日時」「注文アイテム一覧」を持つ
  • 合計金額は Order が計算する
  • 責務が明確に分かれている

Step 5:複数クラスを組み合わせて注文を作る

ここまで作ったクラスを使って、 実際に注文を作ってみます。

using System;

class Program
{
    static void Main(string[] args)
    {
        // 顧客を作成
        Customer customer = new Customer(1, "山田太郎", "yamada@example.com");

        // 商品を作成
        Product p1 = new Product(101, "ノートPC", 120000m);
        Product p2 = new Product(102, "マウス", 2000m);
        Product p3 = new Product(103, "キーボード", 5000m);

        // 注文を作成
        Order order = new Order(1001, customer);

        // 商品を注文に追加
        order.AddItem(p1, 1);
        order.AddItem(p2, 2);
        order.AddItem(p3, 1);

        // 注文情報を表示
        order.ShowInfo();

        Console.ReadLine();
    }
}
C#

実行すると、 注文アイテムが一覧で表示され、 合計金額も計算されます。

Step 6:オブジェクト指向の観点で振り返る

1. 責務が明確に分かれている

  • Customer:顧客情報
  • Product:商品情報
  • OrderItem:商品+数量
  • Order:注文全体の管理

それぞれが「自分の仕事」だけを担当しています。

2. クラス同士の依存が適切

  • OrderOrderItem に依存
  • OrderItemProduct に依存
  • OrderCustomer に依存

依存関係が自然で、 「どこが何を知っているか」が明確です。

3. 拡張しやすい設計になっている

  • 商品カテゴリを追加したい
  • 顧客ランクを追加したい
  • 注文ステータス(enum)を追加したい
  • 割引機能を追加したい

など、 新しい機能を追加しやすい構造になっています。

Step 7:応用アイデア(発展)

ここからさらに発展させると、 より実践的な注文システムになります。

  • OrderStatus(enum)を追加
  • IPriceCalculator インターフェースで割引計算を抽象化
  • OrderService を作って注文処理を分離
  • record を使って Product をデータクラス化
  • struct を使って「数量」や「金額」を型安全に扱う

第5章で学んだ内容が、 すべてこの注文システムに応用できます。

Day 50 のまとめ

Day 50 では、

  • Customer
  • Product
  • Order
  • OrderItem

という4つのクラスを連携させて、 簡易注文システムを作りました。

この演習を通して、

  • クラスの責務分担
  • 複数クラスの連携
  • データ構造の設計
  • オブジェクト指向の考え方
  • 拡張しやすいコードの書き方

を実践的に体験できたと思います。

第5章は「オブジェクト指向の深い部分」を扱いましたが、 Day 50 の演習でそれらがひとつにつながり、 「設計できる」という感覚が少しずつ育ってきたはずです。

次の章では、 このオブジェクト指向の基礎を土台に、 より実践的な C# の世界へ進んでいきます。

タイトルとURLをコピーしました