出席簿をつけるアプリケーションを想定してみることにします。まずマスターとして、学生、講師、講義の 3つが存在するものとします。
学生
講師
講義
それから、マスター以外のテーブルとして、受講者リストと出席記録があるものとしましょう。
受講者リスト
出席記録
さて、ログインした講師が受け持つ講義の 1つを選択し、新たに出欠をとる画面を開いたとします (講義回数は自動でカウントされるべきでしょう)。その画面には講義に参加する全ての学生が学籍番号順にリストアップされており、点呼を受けて講師自らが学生たちの出欠状況を入力していくものとします。これをどうプログラムで表現し、実装するべきか。
オブジェクト指向をメタファー (隠喩) の表現のために用いること自体は必ずしも間違いではありませんが、メタファー自体も手段の一つと捉えるべきです。メタファー自体が目的になってしまうと、パフォーマンスが犠牲になることが多くなります。
例えば学生と講師はどちらも人なので、 Person
クラスで抽象化して Student
と Teacher
に派生しよう、などと考えること自体は悪くないかも知れません。
// 人を表す抽象クラス public abstruct class Human { // 人を特定する番号 (学籍番号、教員番号等) public long Number { get; protected set; } // 名前 public string Name { get; protected set; } // 性別 ("M": 男性 / "F": 女性 / "O": その他) public string Sex { get; protected set; } // etc... } // 学生クラス public class Student : Human { // 学年 public int? Year { get; private set; } // ... } // 講師クラス public class Teacher : Human { // 役職 (11:助教 / 16:講師 / 21:准教授 / 26:教授 / 51:名誉教授 / 56:客員講師 / 99:その他) public int Roll { get; private set; } // ... }
あー、ちなみに言語は C# で書いてます。テストしてませんが。
で、ここまでは良いんですが、ありがちな誤りとして、それぞれのクラスのコンストラクタに DB からの読み込み機能を持たせちゃうという試みがあります。
using Db = MyNameSpace.DbAccessor; public class Student : Human { // ... // デフォルトコンストラクタ (マスタ登録時用) public Student() { } // コンストラクタ (学籍番号から情報を取得) public Student(long number) { DataTable table = Db.StudentTable.SelectByPk(number); if (table == null || table.Rows.Count == 0) return; DataRow row = table.Rows[0]; Number = number; Name = row["STUDENT_NAME"] as string; Sex = row["STUDENT_SEX"] as string; Year = row["STUDENT_YEAR"] as int?; // ... } // ... }
さすがに面倒くさいので Teacher
の方の実装例は割愛。
何故にこれがアカンのかと言いますと、まぁ例外との兼ね合いというのもあるのですが、何よりあまりにも気兼ねなく使え過ぎちゃって、知らず知らずのうちに無駄な DB アクセスが増えてしまう要因になりうるからです。あと、実際の使用に際しては実はあまり使われることのない存在になる可能性も小さくありません。
セコメントをする