web-dev-qa-db-ja.com

C#.NET MVVMソフトウェアのアーキテクチャと命名規則

現在、MVVMパターンでC#.NETおよびWPFを使用するソフトウェアに取り組んでいます。

ソフトウェアはほぼ完成しましたが、私はアーキテクチャについて長い間議論してきました。コンベンション/グッドプラクティスの側面について、意見や助言を得たいと思います。

現在のアーキテクチャは次のとおりです。

  • 事業/
    • DataContext /
    • モデル/
      • Engine3D /
      • ...
    • ユーティリティ/
      • コンバーター/
      • 静力学/
    • ViewModels /
      • グリッド/
      • メニュー/
      • ウィンドウズ/
      • ...
    • ビュー/
      • グリッド/
      • メニュー/
      • ウィンドウズ/
      • ...

モデルフォルダ:

MVVMパターンのモデルが含まれています。

Modelsフォルダーは、機能ごとに整理されています。つまり、3Dに関連するすべてのモデルのModels/Engine3Dなど、機能またはコンテキストにちなんで名付けられたネストされたフォルダーがあります。

「モデル」という単語をサフィックスとして追加することはありません。ファイル名は[Feature].cs 例えば、 Project.csModel3D.csAnimation.csなど...

ビューフォルダ:

MVVMパターンからのビューが含まれています。

ViewsフォルダーはWPFコントロールによって編成されています。つまり、WPFコントロールにちなんで名付けられたフォルダーがネストされています。たとえば、WPFウィンドウに関連するすべてのビューのビュー/ウィンドウ、またはビュー/グリッドなどです。

ファイルの名前は[Feature] [ControlType] .xamlで、次のようになります。

  • [機能]:ビューによって実装/説明される「機能」。たとえば、プロジェクトを作成する機能の「CreateProject」、Model3Dを表示するグリッドのDisplay3DModel(3Dライブラリを使用)など。
  • [ControlType]:ファイルによって表される「xaml」コントロールのタイプ。ウィンドウ、UserControl、グリッドなどです。例として、システム設定を表示するウィンドウはSystemPreferencesWindow.xamlと呼ばれ、グリッドはすべてのプロジェクトのリストを保持するのはProjectsListGrid.xamlです。たとえば、CreateProjectWindow.xaml、SystemPreferencesWindow.xaml、Display3DModelGrid.xaml、ProjectsListGrid.xaml

ViewModelsフォルダー:

MVVMパターンのViewModelが含まれています。

ViewModelsフォルダーは、アーキテクチャーの観点からViewsフォルダーをコピーします。つまり、WPFコントロールにちなんで名付けられたネストされたフォルダーがあります。たとえば、WPFウィンドウに関連するすべてのViewModelのViewModels/Windows、またはViewModels/Gridsです。

ViewModelファイルは、関連するViewファイルと同じ名前で、サフィックス「ViewModel」が付いています。ファイルには、[Feature] [ControlType] ViewModel.csという名前が付けられています。

たとえば、View => ViewModel:CreateProjectWindow.xaml => CreateProjectWindowViewModel.cs、OpenProjectWindow.xaml => OpenProjectWindowViewModel.csなどに基づいています。

DataContextフォルダー:

つまり、DataContextファイルが含まれています。ソフトウェアの特定のコンテキストに関連するファイル。これらはViewModelでもモデルでもないクラスであり、ほとんどが「静的」にアクセスでき、ソフトウェア実行フローの非常に特定のコンテキストに対応しているため、Utilitiesフォルダーには属していません。これらのクラスは、たとえば、Webテクノロジーのセッションなど、ユーザーに関するセッション値を保持するSessionクラスです。

ユーティリティフォルダ:

さまざまな目標のファイル/クラスツールのセットが含まれています。

  • MVVMデータバインディングを許可するObservableObject.cs、DelegateCommand.cs、RelayCommand.csなどのソフトウェア全体にシステムメカニズムを提供する定義クラス...
  • Utilities/Convertersフォルダー:Convertersクラス...
  • Utilities/Staticesフォルダー:入力を受け取り、出力を返す静的操作クラスが含まれます。たとえば、FileOperations.cs、XWindow.cs(名前に煩わされることはありません。プロジェクト固有です)は、InvokeWindow()のようなSystem.Windows操作を再グループ化します。コードでSystem.Windowsを操作しやすくするためのCloseWindow()、3Dモデルを非常に簡単にインポートするModel3DImporter.cs、シリアル化操作用のSerializationManager.csなど.

定数を持つクラス:

一部のクラスは定数値を必要とし、これらの値はコードのほとんどどこからでもアクセスする必要があるため、これらの定数値を関連クラスではなく「姉妹」クラスに格納しました。

これらの「姉妹」クラスは次のとおりです。

// The sister class
public static class Model3DConstants
{
    private static readonly IList<String> supportedFileExtensions = ...
}

// The original class
public class Model3D
{
}

私がメッセージの冒頭で述べたように、私たちには何かが欠けていると確信していますが、何がわからないので、私たちのアーキテクチャ/命名規則についてのあなたのアイデア/アドバイスをお願いします。

WPFを使用して正しいC#.NET MVVMソフトウェアで行うべきこととはまったく逆のことをしていますか?修正する必要のある欠陥やものは何ですか?

上記の説明が不明な場合は、遠慮なく討論に参加するか、質問してください。

6
Rashimov Azarov

これはあなたが求めているすべてに答えるわけではありませんが、コメントには多すぎます。

ソリューションの組織(私はアーキテクチャーではなく組織という用語を使用します)は、それをどのように使用するかを反映する必要があります。それはあなたの使用のために効率的でなければなりません。たとえば、メニューに変更を加えたい場合、開発者は変更を行うためにView/MenusおよびViewModels/Menusからもファイルを開く必要がありますか? (これは非効率的です。)または、ビューのみを開くデザイナーと、ビューモデルのみを開く開発者がいますか?

これが、単一のチームプロジェクトが機能指向のアプローチ(同じ機能フォルダー内の関連するビューとビューモデルを使用)を好むかもしれないのに対して、複数のチームを含む大規模なプロジェクトは、現在の構造のようなコンポーネント指向のアプローチを好むかもしれない理由です。 (これも コンウェイの法則 の理由かもしれません。)

私はユーティリティとインフラストラクチャを(少なくとも精神的に)区別しています。インフラストラクチャコードは、ポリシーによって使用されるアプリケーションの内部動作の中核部分です(たとえば、「これらのWPFコントロールでは常にRelayCommandを使用します。」-UIインフラストラクチャ)。一方、ユーティリティは、一般に、おそらくFileOperationsのような便利な専用関数です。新しいインフラストラクチャプロジェクトを作成したり、名前を変更したりすることはお勧めしません。すべての「使用する必要がある」コンポーネントがアクセスしやすい場所にあることを確認してください。

ユーティリティコードは、忘れられたり無視されたりするリスクが最も高くなります。したがって、そこに置くものが本当に便利で時間を節約できることを確認してください。多くのマイナーヘルパーで汚染する場合、他の開発者は時間をかけて慣れるのではなく、時間を節約する機会を逃します。

そして、いくつかの特定のコンポーネント全体で役立つ再利用可能なコードと私が考えるものであるヘルパーがあります。多分それは関連機能に使用される共有コードです。ユーティリティではなく、可能であれば、通常これらを呼び出しコードに近づけます。このようにして、開発者がその機能に取り組む必要がある場合、コードはそれほど遠くなく、再利用性の高いユーティリティに粗末を追加しません。

開発者mustインフラストラクチャに精通しているshouldユーティリティに精通しているmay特定の機能のヘルパー(彼らがその機能に取り組んでいる場合)。

7
Kasey Speakman

プロジェクトの構造は、プロジェクトの目的と意図を反映する必要があります。

あなたの質問から、そしてあなたのプロジェクト構造から、私はあなたのプロジェクトの目的と意図が何であるかわかりません。しかし、プロジェクトが何であるかについていくつかの光を当てるなら、私はディレクトリ構造についていくつかの提案を与えることができると確信しています。

Viewsディレクトリ、ViewModelsディレクトリ、Modelsディレクトリを使用することで、MVVMパターンのクラスの役割に従ってコードを整理します。この設計パターンによる構造により、プロジェクトはMVVMパターンの使用方法のサンプルプロジェクトのようになります。

プロジェクトはモジュール式である必要があります。

残念ながら、デザインパターンの役割構造はモジュール化を妨げます。つまり、AwesomeModelAwesomeViewAwesomeViewModelAwesomeディレクトリに一緒に含めることはできません(特別なAwesomeCollectionクラスも必要な場合はどうしますか?)。

プロジェクト構造はスケーリングする必要があります。

プロジェクト構造をスケーリングするには、プロジェクトがより面倒に見えることなく、より多くのクラスを持つことができるようにする必要があります。 20個のビューモデルが含まれるViewModelsディレクトリは混乱しているため、これはデザインパターンのロール構造に対しても無効です。

スケーラブルなプロジェクト構造は、静的な一連のディレクトリにすることはできません。

ただし、SharedCommon、またはUtilitiesディレクトリに一般的な詳細を格納すると、非常に役立ちます。自社開発のフレームワークがあります。 Utilitiesディレクトリに10以上のサブディレクトリができたとしても、少なくともルートディレクトリが乱雑になることはありません。 Utilitiesディレクトリに入るのは、取り除くのが最も難しくなるものなので、これをやりすぎないようにしてください。一部のユーティリティクラスは、複数のアプリケーションで使用できるように成熟していますが、最初のアプリケーションに移行することもできます。