導入
レッスン10の TaskFactory でタスクを作れるようになりましたが、作った TaskItem はローカル変数に入っているだけで、メソッドを抜ければ消えてしまいます。タスク管理アプリとして成立させるには「タスクを保持し、あとから一覧・検索できる」場所が必要です。
図解
classDiagram
class ITaskRepository {
<<interface>>
+Add(TaskItem) void
+All() IReadOnlyList~TaskItem~
+FindById(Guid) TaskItem
}
class InMemoryTaskRepository
class FakeTaskRepository
ITaskRepository <|.. InMemoryTaskRepository
ITaskRepository <|.. FakeTaskRepository
TaskService --> ITaskRepository : 抽象にだけ依存
サンプル
Repository(リポジトリ)パターンは「データの出し入れ」を、コレクションのような窓口に隠す設計です。詳しい解説はC#デザインパターンコースのレッスン20にあるので、ここでは要点だけ復習します。
interface IContactRepository { void Add(string name); int Count(); }
class InMemoryContactRepository : IContactRepository
{
private readonly List<string> _contacts = new();
public void Add(string name) => _contacts.Add(name);
public int Count() => _contacts.Count;
}
var repo = new InMemoryContactRepository();
repo.Add("田中");
repo.Add("鈴木");
Console.WriteLine(repo.Count()); // 2
- 呼び出し側(業務ロジック)は
IContactRepositoryという抽象にだけ依存する - 保存の実体(リストか、DBか、ファイルか)は実装クラスが決める。呼び出し側は知らなくてよい
- 次のレッスンから、この形をそのまま
TaskItem向けのITaskRepositoryとして作ります
やってみよう
InMemoryContactRepository に All()(IReadOnlyList<string> を返す)を増やし、foreach で一覧を表示してみましょう。呼び出し側のコードは1行も変わりません。
演習
interface IContactRepository { void Add(string name); int Count(); }
// TODO: リストに溜めて Count() で件数を返す InMemoryContactRepository を実装してください
___
var repo = new InMemoryContactRepository();
repo.Add("田中");
repo.Add("鈴木");
Console.WriteLine(repo.Count()); // 2
ヒント1を見る
class InMemoryContactRepository : IContactRepository { private readonly List<string> _contacts = new(); public void Add(string name) => _contacts.Add(name); public int Count() => _contacts.Count; }
ヒント2を見る
内部でList<string>に溜め、Countはそのリストの件数を返します
まとめ
- Repositoryは「データの出し入れ」を抽象化した窓口
- 呼び出し側は具体的な保存先を知らず、インターフェースにだけ依存する
- 次のレッスンからこの形を
TaskItemに適用します
次回: 契約どおりの ITaskRepository と InMemoryTaskRepository をTDDで実装します。