5


0

プレゼンテーションの値の変換は、多層アーキテクチャのどこで行われますか?

多言語、マルチタイムゾーン、n層のアプリケーションを構築しています。 すべての日付はUTCでデータベースに保存され、すべてのモデルオブジェクトにはUTC時間が設定されます。 ただし、UTC時間は表示されません(ユーザーがたまたまタイムゾーンをUTCに設定していない限り)。

これは、時間プロパティを正しいユーザータイムゾーンに繰り返し変換する必要があることを意味します。 繰り返しは常に悪いコードまたはより良い方法の兆候であるため、私は実装するための最良の戦略を練ろうとしていました。 これは効果的なプレゼンテーションロジックですが、モデルが現在のユーザーの適切な値を認識しているように見えるため、私の考えはさまざまです。 これまでのところ、私の考えは次のとおりです。

  1. 静的ヘルパークラスを使用し、プロパティのたびにそれを呼び出します モデルが使用されます。 これはエラーを起こしやすいか忘れられがちで、計算や計算が面倒です。

  2. モデルオブジェクトをviewmodelオブジェクトでラップします。 これは等しく 特にオブジェクトのリストを扱うときは面倒です。

  3. にのみ存在するモデルの拡張メソッドを記述します プレゼンテーション層 これは見た目はすっきりしていますが、直感的ではありません。

  4. 変換用のモデルレイヤーにインターフェイスを作成します。 実装する プレゼンテーション層のヘルパー。モデル層に実装を提供します。 モデルには、インターフェースを使用して時間を変換するプロパティがあります。 これは、懸念の分離を破るべきであるように見えますが、そうは見えません。 デフォルトのコンバーターがあれば、nullオブジェクト例外の取得を心配する必要はありませんが、モデルレイヤー(現在はPOCO)には、変換ヘルパーのコンテナーが必要になります。

  5. モデルでローカルタイムゾーンへの変換メソッドを作成し、 現在のタイムゾーン。

これらの戦略や、これらの戦略の代わりに使用すべき、または使用できるその他の戦略についての意見に興味があります。

*更新*現在行っているのは、モデルレイヤー内にITimeConvertorとITimeConvertorFactoryを作成することです。 次に、元の日付値を返すだけのこれらのデフォルト実装を作成しました。 モデルレイヤー内に、元々モデル上にあった既存の各UTCプロパティにローカルタイムプロパティを追加しました。 これらのプロパティ内で、ファクトリーを使用してコンバーターを取得し、ゲッターとセッターでそれぞれの方法でUTC値を変換します。 現在のタイムコンバーターファクトリを格納する場所として、静的な設定クラスをモデルレイヤーに追加する必要があります(これはあまり好きではありません)。 Webアプリの部分内で、ITimeConvertorFactoryおよびITimeConvertorをWebTimeConvertorFactoryおよびWebTimeConvertorとして実装します。 WebTimeConvertorはセッションと現在のユーザーを知っているため、現在のタイムゾーンを取得できます。 WebTimeConvertorFactoryはWebTimeConvertorsを作成します。 アプリケーションの起動時に(global.asaxのapplication_onstart)ファクトリを作成し、モデルレイヤーの静的設定プロパティに渡します。 これにより、データレイヤーはUTC日付プロパティのみを知っている一方で、モデルレイヤーは現地時間を変換できます。 また、ローカルタイムをモデルに直接渡し、消費アプリがコンバーターファクトリーを提供していれば、正確に変換できることも意味します。 UTCプロパティは変更されていないため、アプリ内のどこでも使用できます。 多くのコードのように見えますが、このソリューションは実装された後はきれいであることがわかりました。明らか。

より良い解決策と、現在の解決策に対する批判に対して、私はまだオープンです。

1 Answer


2


ユーザーのタイムゾーンを知っているのはモデルレイヤーであるため、時間プロパティを変換するのはモデルレイヤー次第です。 それ以外の場合は、プレゼンテーションレイヤーにタイムゾーンを通知し、そこで時間値を変換する必要があります。

モデルレイヤーで時間値を変換すると、変換せずにプレゼンテーションレイヤーで時間値を使用できるようになるので、きれいだと思います。 たとえば、最初に変換された時間でオブジェクト(POCO)を初期化できます。 ただし、モデルでそれらを再変換し、すでにローカル時間に初期化されていることを忘れてください。 また、ユーザーが時間値を編集できる場合は、保存する前にUTC時間に変換する必要があります。

*更新:*少し考えてから、UTC時間はモデルの一部であり、現地時間はこのモデルのビューであるため、変換の義務はプレゼンテーション層に属します(自分自身に反対することを犠牲にして)。 同じ思考プロセスで、UTC時間と共に現地時間のプロパティを持つことは本質的に重複しており、変換はまだモデルレイヤーにあります。 これを克服するために、タイムゾーンで初期化されるユーザーPOCOに読み取り専用の UTCToLocalTimeConverter-typeプロパティがあるかもしれません(静的メソッドも不要です)。 次に、ページ内の時間プロパティへのすべての呼び出しは、ユーザーのアクセスが可能なコンバーターの `ConvertToLocalTime`メソッドでラップされます。 必要に応じて、コンバータインスタンスを直接「セッション」に配置することもできます。

このアプローチがあなたにとってうまくいくかどうかはわかりませんが、それはあなたの戦略に触発されており、デザインの残りの部分はこのように考えるとよりスムーズに動作すると思います。 また、現地時間への変換もクライアントの自由です。 欠点は、クライアント内のすべての時間値を変換する必要があることですが、それはデータ重複と静的メソッドを取り除くことと引き換えに必要な悪のように思えます。