C#でドメイン駆動開発

C#でドメイン駆動開発 Entityの書き方と使い方とテスト駆動!⑨

ドメイン駆動開発では意味のあるひとかたまりのデータをEntityとして扱います。データベースの1行分のデータと考えるといいと思います。

Entity

先ほどはGetDataの戻り値がfloatでした。実務では複数の項目を返却するシナリオのほうが断然多いでしょう。

今回はデータベースの1行分の値

「計測ID」

「計測日時」

「計測値」

を返却するシナリオを返却するシナリオを考えてみましょう。

 

データベースのテーブルをSELECTしたりINSERTなどに使用するひとかたまりをドメイン駆動開発ではEntity(エンティティ)と呼びます。

Entityの決め事としては,「一意」であるということです。同じEntityが複数あってもその一つを特定できる必要があります。

データベースのプライマリキーと同じです。ですのでDBからSELECTした1行がEntityだという理解でよいと思います。

今回の例では「計測ID」がKeyとなります。中身はstringでGuidの文字列が入っているということにしましょう。

GuidとはC#ではGuid.NewGuid().ToString()で得られる文字列で,マックアドレス並みに一意になる値といわれています。(完全に重複しないわけではないがほぼないものという感じです)

Entityの作成

Entityを作ってみましょう。まずDomain層に新規フォルダで「Entities」を作成します。その中に新規クラスで「MeasureEntity」を作成します。

語尾のEntityはつけない人もいますが,私はつけたほうがわかりやすいと思うのでつけています。※つけたほうが名前を見ただけでそのクラスの使われ方が想像できる

まずコンストラクタではプロパティで使用する値すべてを受け取っています。完全コンストラクタパターンといわれるものですが,可能な限りこのパターンのほうがコードの見通しは良くなります。

要するにMeasureIdだけ設定してあとは設定していないなどという実装ができなくなります。

コンストラクタでNullの可能性のある変数のNullチェックをしていればなおよいでしょう。

この場合であればstringだけがNullの可能性があります。今回はこのままいくとしましょう。エンティティの紹介のため先に本番コードを書きましたが,実際はテストコードから記述します。

それではテストコードを書いていきましょう。Testsプロジェクトにテストクラスを新規で作成しましょう。名前はLatestViewModelTestとしましょう。

直近値の値を表示する画面のViewModelとします。テストコードを書きましょう。

LatestViewModelがコンパイルエラーになっているのでWinFormのViewModelsにLatestViewModelを作成しましょう。

前回と同じようにアクセス修飾子をpublicにしてViewModelBaseを継承します。

LatestViewModelTestに戻り,LatestViewModelの行でCtrl+ドット,Enterを行って,usingを追加します。

ここで一度テストしましょう。テスト結果は成功するはずです。次にテストコードを書いていきます。

MeasureDateとMeasureValueがコンパイルエラーになっているのでそれぞれをCtrl+ドット,Enterで自動生成します。

自動生成したコードをデータバインドできる形に書き換えます。内容はMeasueViewModelでやったのと同じ形です。

テストをしましょう。NGになります。今回はいきなり日付と計測値を表示するようにテストコードを書いたため,テストは通りません。今回はデータベースから値をとる想定です。

データベースにはMeasuresというテーブルがあって,その直近値を取得するシナリオです。

IMeasureRepositoryというリポジトリーを作成しましょう。

最初に作成したEntityを返却するように定義しています。これをViewModelから呼び出します。

これで一度テストしてみましょう。コンパイルエラーになります。テストコードでLatestViewModelへのコンストラクタに引数をセットしていません。今回もMoqをしようしてMockを作成しましょう。

テストを実行します。成功すると思います。UIとインフラストラクチャを作成しましょう。WinFormのViewsフォルダに「LatestView」というFormを作成し,ラベルを一つ貼り付けてNameをMeasureValueLabel,フォントを36とします。画面のコードを表示しつぎのように書きます。

画面タイトルに日付,今回追加したラベルに計測値が出るようにバインドしています。LatestViewModelの生成でコンパイルエラーが出ているので対応しましょう。まずインフラ層のFakeフォルダにMeasureFakeを作成します。

IMeasureRepositoryを実装しGetLatestで適当なMeasureEntityを返却します。Factoriesクラスで今回のクラスが生成できるようにコードを加えます。

LatestViewModelのデフォルトコンストラクタでCreateMeasureRepository()を呼び出しましょう。

【LatestViewModel】

これでLatestViewを表示する準備ができました。ただLatestViewを呼び出す画面がないため,今回新たにMenuViewというFormを追加しましょう。

画像のとおりボタンを配置しそれぞれのボタンよりMeasureView,LatestViewを呼び出せるようにしましょう。

Program.csのMain関数も次のように書き換えます。

これで画面が呼び出せるはずです。実行してみましょう。LatestViewを表示するとタイトルに日時,ラベルに計測値が最初から表示されているはずです。

ドメイン駆動開発