先にも記載した通り、本ユースケースのUIからデータベースまでの相互作用は、基本的に「従業員を閲覧する」ユースケースと違いがありません。本ユースケースをアーキテクチャ設計として記載する目的は、ユーザーインターフェースの詳細な実装アーキテクチャを決定・解説することにあります。そのため、実際のユーザーインターフェースの操作を追いながら、詳細を記述していきたいと思います。プロパティの変更通知の実装さて本ユースケースは、「従業員を閲覧する」ユースケースを拡張して実現します。具体的には、「従業員を閲覧する」ユースケースを実行後、次の画面の「編集」ボタンを押下することでユースケースを開始します。WPFは編集に対応しているところを、「従業員を閲覧する」ユースケースで読み取り専用で表示しているため、編集ボタンを押下することで編集可能に状態を変更することで、ユースケースを開始します。「従業員を閲覧する」ユースケースの解説でもお見せしましたが、XAML上で編集可否を制御している箇所をもう一度見てみましょう。IsReadOnly}"初期はLockedとProtectedの二つのプロパティにtrueが設定されているため、編集ボタンを押下してIsReadOnlyをfalseに変更します。このとき変更を通知するため、通常はINotifyPropertyChangedインターフェースを実装した、次のようなコードを記述する必要があります。}}正直、通知が必要なプロパティに全てこの記述を行うのは苦痛です。苦痛な上に、不具合の温床でもあります。そこで本システムではPropertyChanged.Fodyを利用することとします。PropertyChanged.Fodyを利用することで、先のコードと同等のコードが次のように記述するのみで実現できます。true;}PropertyChanged.FodyはFodyという静的コード生成フレームワークを利用しています。前述のコードではクラスの属性としてAddINotifyPropertyChangedInterfaceが宣言されています。PropertyChanged.Fodyでは、AddINotifyPropertyChangedInterface属性が宣言されたクラスに対して、コンパイル時にコンパイルされたバイトコードを修正して、INotifyPropertyChangedを利用した変更通知に必要な処理を自動的に組み込んでくれます。詳細は英語になりますが、次のサイトが参考になります。編集ボタンと保存ボタンがあります。これらのボタンはそれぞれ、閲覧中は編集ボタンのみが押下でき、編集中は保存ボタンのみが押下できるように、状態を管理する必要があります。ボタン状態ボタンには次のように、ViewModelのEditCommandとSaveCommandをバインドします。SaveCommand}"/>ボタンはバインドされているCommandのCanExecuteがtrueの場合に押下可能となります。ICommandの詳細は次の記事も参考にしてください。WPFやXamarinのICommandを改めて整理するここでは先にも記載した、IsReadOnlyプロパティの状態によって制御すればよいのですが、具体的な実装方法は多数あります。本システムではいずれかのプロパティの状態の変更を受けて、別のプロパティの状態を変更したり、何らかの処理をする場合、ReactivePropertyを利用することとします。ReactivePropertyはMVVMアーキテクチャでリアクティブプログラミングを容易に利用するためのライブラリです。詳細は次の記事をお勧めします。実際のコードを見てみましょう。...EditCommandもSaveCommandも、いずれもReactiveCommandとして宣言しており、インスタンスはコンストラクタで生成しています。EditCommandはIsReadOnlyプロパティがtrueの時のみ押下でき、押下するとIsReadOnlyをfalseに変更するよう実装しています。SaveCommandは逆にIsReadOnlyがfalseの時のみ押下でき、押下するとOnSaveメソッドを呼び出すように実装しています。リアクティブプログラミングのメリットは、さまざまな解説がされていますが、私は上記コードのように条件と振る舞いを宣言的に記述できることに大きなメリットを感じています。仕様をコードでそのまま表現できる感覚が気に入っています。Frameworkから始まって、現在は多種多様なプログラミング言語に輸出されています。取っ掛かりに困難を感じることもあるかもしれませんが、その困難を乗り越える努力を払う価値が十分にあるでしょう。ReactivePropertyはリアクティブプログラミングへの入門としても非常に優れたライブラリです。ReactivePropertyのはじめの使い方グリッドの各行の編集状態の管理グリッドの各行は次の三つの状態を取ります。UnModifiedModifiedNewこの状態を1行を表すManagedEmployeeViewModelクラスで管理します。実際のコードを見てみましょう。...}先に記載した、「従業員を閲覧する」ユースケースのコードに大きく二つの修正を加えています。一つはEditStatusプロパティを追加したこと。先に記載した三つの状態の何れかを表します。一つは、自分自身のPropertyChangedイベントを監視し、EditStatusがUnModifiedで更新されたプロパティがEditStatus以外だった場合に、EditStatusをModifiedに変更する処理を追加しています。することでグリッド上で既存の行を更新されたときに、ViewModel側で変更された行を検知できるようにしています。新たに行が追加された場合には、ManagedEmployeeViewModelのデフォルトコンストラクタが呼び出されます。WPFでは、バリデーションの実現方法を、データソースに実装する検証やイベントによる継承、DataAnnotationによる検証など、複数用意しています。本システムでは、DataAnnotationを利用しています。DataAnnotationによるバリデーションは、ViewModelのプロパティに属性を指定することで実現します。次のコードは、姓が必須であることを表しています。チェックでエラーになった場合、次のように表示されます。バリデーションエラーのある項目にマーカー(ここでは赤い三角)が表示され、エラーのある項目にフォーカスが当たると任意のエラーメッセージが表示されます。Frameworkが提供している仕組みで、次のページで標準でサポートされているDataAnnotationを確認することが可能です。名前空間グリッドの編集状態をサービスへ通知し、データベースを更新する更新のトリガー処理は既に先に記載済みです。XAML上でButtonのCommandにViewModelのSaveCommandがバインドされており、SaveCommandが実行されると、ViewModelのOnSaveメソッドが呼び出されます。OnSaveメソッドの実装は次の通りです。LoadManagedEmployees();}次の手順で更新処理を実施しています。新規追加行のViewModelを取得し、Commitを呼び出した後、ManagedEmployeeのListの作成IHumanResourcesServiceを呼び出して、データベースへの追加・更新を実行グリッドを一旦クリア従業員情報を再ロードCommitの実装は次のようになっています。_managedEmployee;}ViewModelの編集状態をManagedEmployeeの値に上書き更新し、更新後のManagedEmployeeを返却しています。従業員情報を再ロードしているのは、再ロードすることでEmployeeテーブルなどのModifiedDateを取得し直し、更新の衝突処理を実装できるようにする意図があります。今回のサンプルではそこまで実装されていません。実装ビューの解説は全てとなります。さいごにさて、ここまで特定のビジネス・システム化の背景を想定して、求められるシステムを構築するためのアーキテクチャを検討・記載してきました。ビジネス要件、システム要件、非機能要件が明確になりきっているとは言えないため、アーキテクチャも不鮮明な部分が残ってはいます。それでもアプリケーションを構築する際のヒントには十分になりえるのではないかと思います。本稿が、アプリケーション構築にお悩みの方の一助になれれば幸いです。<123連載通知を行うには会員登録(無料)が必要です。会員の方はログインを行ってください。金融ソリューション開発部所属。圧縮・解凍UNIX基本講座@CodeZine『CodeZine(コードジン)』の公式アカウントです。【NEW】デブスト2019デブサミ2019福岡・関西デブサミ2019夏デブスト関西デブサミ2019×ログインEメールパスワード※旧SEメンバーシップ会員の方は、同じ登録情報(Eメール&パスワード)でログインいただけます。イラストの無断転載を禁じます。記載されているロゴ、システム名、製品名は各社及び商標権者の登録商標あるいは商標です。