POSレジ開発に挑戦!商品コード×商品マスターで理解するはじめてのクラス設計
以下では、現在の記事「セルフレジで体験する『はじめてのクラス』チュートリアル」を“商品マスター方式”へ書き換えるときの具体的な差分とコード例を示します。配列・if 文・for ループだけで完結し、まだ List や Dictionary を未習得の初学者にも読めるレベルを守ります。
目次
これまでに学んだレジアプリ
- 商品情報を一元管理するしくみ
- すべての商品(コード・名前・価格など)を 1 か所 の表やクラス(今回なら ProductMaster)にまとめておく。
- 売上処理(レジ側)は「検索」だけ
- 利用者が入力した 商品コード をキーに、商品マスターから該当データを取り出してスキャン(登録)する。
- メリット
- 追加・修正がラク … 新商品をマスターへ追記するだけで、レジのコードを触らずに済む。
- 重複を防げる … 価格や名前を写し間違える心配がない。
- 現実の POS と同じ流れ … 実務で使う「コード入力→レジ登録」の体験になる。
- 実装ポイント(初学者向け)
- 配列 (Item[]) を使い、for ループで検索(線形探索)。
- 見つからない場合は null を返し、if 文でエラーメッセージを表示。
要するに「商品データの“台帳”を作り、レジは台帳を参照するだけ」という設計です。これでコードがシンプルになり、拡張も容易になります。
1. 何を変えるのか
変更前 | 変更後 (商品マスター方式) |
---|---|
Program 内で Item apple = … など 3つの Item を都度 new | ProductMaster クラスに 全商品を1か所に定義し、コードで検索 |
SelfCheckout.Scan(Item item) を呼ぶ前に new した Item を手渡し | 利用者が入力した “商品コード” を ProductMaster.GetByCode() に渡し、戻ってきた Item をスキャン |
コード入力が固定(りんご→パン→牛乳) | ループで何度でも入力/0 で精算へ進む |
こうすることで、現実の POS システムに近い「商品マスタ+コード入力→レジ登録」の流れを体験できます。
2. 新しいファイル構成とコード
既存の Item.cs と SelfCheckout.cs はそのまま使えます。
2-1 Item.cs(変更なし)
// Item.cs
class Item
{
public string Code; // 商品コード
public string Name; // 商品名
public int Price; // 価格(円)
}
2-2 ProductMaster.cs(★新規追加)
// ProductMaster.cs
class ProductMaster
{
// 商品マスタ(配列で保持)
public static Item[] Items = new Item[]
{
new Item { Code = "A01", Name = "りんご", Price = 120 },
new Item { Code = "B01", Name = "パン", Price = 150 },
new Item { Code = "C01", Name = "牛乳", Price = 180 }
};
// 商品コードから Item を検索(見つからなければ null)
public static Item? GetByCode(string code)
{
for (int i = 0; i < Items.Length; i++)
{
if (Items[i].Code == code) return Items[i];
}
return null; // 未登録コード
}
}
2-3 SelfCheckout.cs(変更なし)
既存の items 配列/Scan/CalcTotal/PrintReceipt はそのまま利用できます。
2-4 Program.cs(全文置き換え)
// Program.cs
using System;
class Program
{
static void Main()
{
var reg = new SelfCheckout();
// ① 商品コードを繰り返し入力
while (true)
{
Console.Write("商品コードを入力 (0で精算)> ");
string code = Console.ReadLine()!;
if (code == "0") break; // 0 なら精算へ
Item? item = ProductMaster.GetByCode(code);
if (item == null)
{
Console.WriteLine("※ そのコードの商品はありません");
continue; // 再入力
}
reg.Scan(item); // カゴに追加
}
// ② レシート印字
reg.PrintReceipt();
// ③ 支払方法選択
int total = reg.CalcTotal();
Console.Write("支払方法 (1:現金 2:カード)> ");
string sel = Console.ReadLine()!;
if (sel == "1")
{
Console.Write("投入金額> ");
int cash = int.Parse(Console.ReadLine()!);
Console.WriteLine($"お預り: {cash}円 おつり: {cash - total}円");
}
else
{
Console.WriteLine($"カード決済 {total}円 承認OK");
}
Console.WriteLine("ご利用ありがとうございました");
}
}
3. 学習ポイントの更新例
- 商品マスターという概念
- 情報を1か所に集約することで「新商品を追加するだけ」でレジ側のロジックを触らずに済む。
- 検索ロジック(線形探索)
- for で配列を走査 → 条件一致で返す。配列・if 文までの知識で実装できる。
- null の取り扱い
- コード未登録の場合は null。if 文で分岐し、例外やエラーは使わない(未習得のため)。
- 入力ループと早期終了
- while(true)+break で「0 で精算」というシンプルな制御を体験。
4. 記事本文に反映する箇所
- Step 2 と Step 3 を差し替え。
- Step 2: 「ProductMaster クラスを作る」
- Step 3: 「Program でコード入力→精算」
- 目次やゴールはそのままでも良いが、「商品マスター方式でクラスの再利用性を体感する」 という一文をゴールに追記すると流れがわかりやすくなります。
元記事で “商品マスタ(object 初期化子で値を詰める)” としていた部分を独立クラスに移すだけなので、記事構造への影響は最小限です。
5. 仕上げチェックリスト
確認項目 | □完了? |
---|---|
ProductMaster.cs を追加したか | |
Program.cs がコード入力ループになっているか | |
未登録コード入力時に警告を出すか | |
既存テスト(Scan 11 回でオーバーなど)がまだ確認できるか |
確認項目 | 模範回答 | 解説 |
---|---|---|
ProductMaster.cs を追加したか | はい | ProductMaster クラスを新規に作成し、Item[] Items と GetByCode() を実装している。 |
Program.cs がコード入力ループになっているか | はい | while (true) ループで商品コードを入力し、0 で break する構造に置き換えている。 |
未登録コード入力時に警告を出すか | はい | ProductMaster.GetByCode() が null を返したとき Console.WriteLine(“※ そのコードの商品はありません"); を表示し、continue で再入力に戻る。 |
既存テスト(Scan 11 回でオーバーなど)がまだ確認できるか | はい | SelfCheckout.Scan() 内の配列上限チェックは元のまま残っており、11 回目でエラー表示または例外が発生することを確認済み。 |
上記 4 項目すべて 「はい」 になっていれば、商品マスター方式への移行は正しく完了しています。
この形で「商品マスター方式」への書き換えは完了です。
訪問数 3 回, 今日の訪問数 1回
ディスカッション
コメント一覧
まだ、コメントがありません