Boost」など、さまざまなカンファレンスを企画・運営しています。BOOKS(コードジン・ブックス)は、CodeZineの連載からカットアップした、開発現場の課題解決に役立つ書籍シリーズです。2.0の新機能で、「Model-View-ViewModel」という階層分割アプローチを取り入れたアーキテクチャーパターンに沿ったフレームワークです。はじめに、Model-View-ViewModelのアーキテクチャーパターンや階層分割アプローチについて、少し触れておきます。ソフトウェアの規模アプリケーションを作成時に開発者が遭遇する問題のひとつに、「ソフトウェアの規模」の問題があります。ソフトウェアの規模が小さいアプリケーションは、比較的見通しもよく、可読性が高いことから取り扱いもしやすいため、プログラミングの際に大きな問題となることは多くないでしょう。実際にソフトウェアで取り扱う問題は単純なものばかりではありません。加えて「複雑な問題を機械的に間違いなく実施することができる」ことは、ソフトウェアを作成する動機のひとつでもあります。ソフトウェアで複雑な問題を取り扱うと、その複雑さに比例してソフトウェアの規模も大きくなります。規模が大きいソフトウェアを取り扱う場合、何も考慮せずソフトウェアを作成すると、元々の問題の複雑さに加えて、ソフトウェアの複雑さが加わる場合があります。その結果、ソフトウェアの可読性・保守性が低下し、ひいては品質の低下につながることになります。複雑なソフトウェアを作成する場合には、それに対応するための対処方法が必要になります。Concerns、略してSoCと呼びます)」があります。SoCでは、ソフトウェアが解決したい問題を個々の問題(関心)毎に分離し、構成する手法です。「大きな問題」を「小さな複数の問題」に分割して扱うことで、一つひとつの問題の複雑さを軽減し、取り扱いやすくするという設計原則です。関心事の分離ただし、やみくもに分割すると、分割の粒度があいまいになることで、問題の粒度が不揃いになり、問題の内容がかえって分かりづらくなったりします。その結果、ソフトウェアの全体像が見えづらくなったり、複雑さが増してしまう場合があります。approach)」です。責任の分割を主な目的としています。ソフトウェアが扱う問題を特定の役割を持つ階層に分割します。分割した各階層は、他の階層への「インターフェース」、つまり窓口だけを取り決めして、その結果を保証します。階層化アプローチ各階層とやりとりを行う「インターフェース」と、「インターフェース」でどのような「データ」を受け渡すかを取り決めます。それ以外の各階層内で行われる処理方法や、階層の内部で使用されるデータについては、他の階層が一切関知しないものとします。それにより、各階層内部は処理やデータの影響範囲を限定されるため、ソフトウェア保守時に掌握すべき項目が減るため、可読性・保守性の向上につながります。Separation、略してPDSと呼びます)」があります。PDSでは、ソフトウェアの「ユーザーインターフェース」部分と「その他の機能」部分を分割することで、以下のメリットを享受できるとしています。(ja)日本語訳)プレゼンテーションロジックとドメインロジックが分かれていると、理解しやすい同じ基本プログラムを、重複コードなしに、複数のプレゼンテーションに対応させることができるユーザーインターフェースはテストがしにくいため、それを分離することにより、テスト可能なロジック部分に集中できるスクリプト用のAPIやサービスとして外部化するためのAPIを楽に追加できる(選択可能なプレゼンテーション部分で見かける)プレゼンテーション部分のコードは、ドメイン部分のコードと違ったスキルと知識が必要ここにあるような分割のアプローチを具現化したアーキテクチャーパターンが、ASP.NETでも利用されているModel-View-Controller(MVC)であったり、これから利用するModel-View-ViewModel(MVVM)などになります。Pagesは、階層化アプローチであるModel-View-ViewModelを用いたフレームワークです。ここで、Model-View-ViewModelについても、少し触れておきたいと思います。Model-View-ViewModelでは、プレゼンテーション部分をView-ViewModel、ドメイン部分をModelに分割して構成します。ViewとViewModelは「データバインディング」のみで関連付けを行うことで、ユーザーインターフェースとデータの分離を実現するアーキテクチャーパターンです。Platform(UWP)などで利用されていたパターンです。WPFやUWPは、ユーザーインターフェースの記述を「XAML」と呼ばれるXMLベースのマークアップ言語で行います。XAMLは、データとユーザーインターフェースの要素を関連付けして、値の同期を実現する、データバインディング機能を持ちます。このデータバインディング機能を使用することで、ViewとViewModelの分離を実現していました。このとき、ViewModelではViewに表示するために必要なデータを「プロパティ」で表現し、Viewはそのプロパティを参照することでユーザーインターフェースの表現に関連付けました。以下の例は、実際にデータバインディングを行っているViewのXAMLとViewModelのC#コードです。ここでは、ViewとViewModelが分離されていることを示す例なので、コードの内容は理解できなくてもかまいません。PropertyChangedEventArgs(propertyName));}この分離によって、Viewに表示されるべきデータが正しく表示できない原因は「正しくデータバインディングが設定されていない」または「ViewModel以降の階層が正しく実装されていない」の2点に限定することができました。ViewModelクラスは、上記のように単独のC#クラスであるため、その他のModelクラスと同様に単体テストの作成も行いやすくなります。View以外のいずれの階層でも単体テストを行うことができるようになったことで、回帰テストが実施しやすくなり、品質の向上に貢献します。Pagesは、このModel-View-ViewModelのアーキテクチャーモデルに倣ってWebアプリの開発が行えるフレームワークです。Pagesではcshtml(Razor構文によるView)-cshtml.cs(PageModelクラスを継承した単一のクラス)-Modelクラスで構成します。RazorPagesとMVVMここで、RazorPagesのテンプレートプロジェクトを見てみましょう。アプリケーション]を選択するか、dotnetコマンドラインで行えます。CLIで行う場合は、任意のフォルダー内で以下のコマンドを実行することで作成されます。razor作成された実際のプロジェクトは下図の通りです。MVCのプロジェクトに比べて、フォルダーが「Pages」のみとシンプルです。「Pages」フォルダーの中には、いくつかのcshtmlファイルが入っていますが、「About.cshtml」「Contact.cshtml」「Error.cshtml」「Index.cshtml」の4ファイルには、関連する「*.cshtml.cs」ファイルが紐づけされています。この「*.cshtml.cs」ファイルが、ViewModelの役割を担う「PageModel」ファイルです。PagesによるWebページの作成方法をまとめると、以下の通りになります。Coreによるテンプレートプロジェクトを少し加工し、「Index.cshtml」と「Index.cshtml.cs」を修正したソースが以下です。Azure、.NETテクノロジーを使用したWebサービスのプロダクトアーキテクト。他にも技術記事の執筆やトレーニング、セミナースピーカーを行っている。プラットフォームチームの意義と実践のポイント1DMM.comの施策から見る、事業をむしばむ「技術負債」への処方箋──リファクタリングの「言語化」でインシデントを予防2企業の7割超が「2025年の崖」を理解していないことが明らかに。プラットフォームチームの意義と実践のポイント1DMM.comの施策から見る、事業をむしばむ「技術負債」への処方箋──リファクタリングの「言語化」でインシデントを予防2企業の7割超が「2025年の崖」を理解していないことが明らかに。プラットフォームチームの意義と実践のポイント1DMM.comの施策から見る、事業をむしばむ「技術負債」への処方箋──リファクタリングの「言語化」でインシデントを予防2企業の7割超が「2025年の崖」を理解していないことが明らかに。NEW新着記事一覧を見るイベント今後の予定を見るCodeZineは、株式会社翔泳社が運営するソフトウェア開発者向けのWebメディアです。「デベロッパーの成長と課題解決に貢献するメディア」をコンセプトに、現場で役立つ最新情報を日々お届けします。イラストの無断転載を禁じます。記載されているロゴ、システム名、製品名は各社及び商標権者の登録商標あるいは商標です。