3

典型的な Web 3 層アプリケーションについて、次の設計 (および理想的なアーキテクチャの提案) にはどのような欠陥がありますか?

私の現在の青写真のアプローチは大まかにこれです(Java、Spring、Hibernate、JSPを想定)


コントローラ

ステートレスで、(遅延初期化例外を回避するために) 読み取り専用トランザクションでラップされる可能性があり、サービスのみを介して永続ストレージからエンティティを取得し、それらをモデルとしてビューに渡します。それらに対してビジネス ロジックを実行し (BL はサービス レイヤーにのみ存在する必要がありますか?)、必要に応じて永続化のためにサービス レイヤーに戻します。

長所: 読み取り専用のトランザクション ラッピングの場合 - 1 つの接続のみ、同じ永続エンティティに対する冗長なヒットがない、クエリ キャッシュをより適切に利用する、サービス レイヤーが要求パラメーターを「認識」してはならない、または必要な init グラフ スパンを使用しない、lazy init 例外を回避する。

短所: 読み取り専用のトランザクション アプローチはリスクが高い可能性があります。コントローラーは理想的なビジネス ロジックのぶら下がり場所ではありません... JUnit を実行するのは非常に困難です (入力は要求です...)


意見

非トランザクション (非遅延コレクション/メンバーへのアクセスは、遅延初期化例外になります)

長所

  • ビューの作成者は、単なるドット表記によってアプリケーションのパフォーマンスに影響を与えるべきではありません (たとえば、大規模なコレクションの遅延初期化による N+1 選択の原因)。

  • また、切断されたクライアント (Flex またはその他のリッチ クライアント) では、リモートでの遅延初期化はサポートされていないか、賢明なことではありません。

短所: コントローラー / サービス / DAO は、ビューのエンティティの適切なグラフを慎重に準備する必要があり、オーバーシュート (パフォーマンス) / アンダーシュート (遅延初期化例外) になる可能性があります。エンティティ グラフを初期化できる順列の数にはデカルト積があるため、無数のサーバー側メソッドが混乱を引き起こす可能性があります。


モデル

永続オブジェクトをそのまま (データ転送オブジェクトなし) 使用すると、状態がセッションに保存されます。

長所: POJO を書き直す必要がない、既存のエンティティを再利用する、セッション状態は非表示フィールドの状態処理よりも安全です。

短所: 切断されたフレームワークには不向きです。切断された古いオブジェクトを保存するリスク、ロックの問題のリスク、他のデータの上書きのリスク、楽観的ロックが必要な場合があります。


サービス

トランザクショナルで、リクエスト スコープがわからないため、実際の永続ストレージ アクセスのために DAO レイヤーを呼び出します。これは、古典的に BL があるべき場所ですが、BL がコントローラー側に何度も漏れているようです。


ダオ

アトミック永続ストレージ ファサード、BL を無視、または任意のコンテキストを含む


最後に、質問:

上記のアーキテクチャで何を修正しますか?

(私のように)それは非常に一般的なアプローチだと思いますか(ビュー内のオープンセッションなど、いくつかの小さな違いがあります)?それとも、あなたがそれを見るのは初めてで、私は何かひどく間違った (または正しい) ことをしているのですか?

アプリケーションでどのように解決しますか? モデルとビューにもエンティティ POJO を使用していますか? それとも、より単純な UI Bean に接続しますか (すべて完全に初期化され、安全です)。

これは主観的な質問かもしれませんが、1 つ、2 つ、または 3 つの最大の一般的な「宗教」に集中する明確なベスト プラクティスの設計パターンがあると確信しています。

4

4 に答える 4

3

全体として、非常に優れたアーキテクチャのようです。まだ読んでいない場合は、Martin Fowlers Patterns of Enterprise Application Architecture をお勧めします。これには、質問のすべての主題が記載されています。

質問からは、パフォーマンスがどの程度の問題であると予想されるかは明確ではありません。私の経験では、パフォーマンスのボトルネックが考えている場所にあることはめったにありません。発見が早け​​れば早いほど、それに合わせてアーキテクチャを簡単に変更できます。

テスト容易性が大きな懸念事項であることは間違いありません。Martin Fowlers Passive View -pattern を使用して、ある程度の成功を収めました。また、同じサイトの Supervising Controller も参照してください。

于 2009-12-28T18:21:06.903 に答える
2

基本的に上記のアーキテクチャのコントローラー部分を取り除くSOFEAスタイルのフロントエンドを実行しない限り、スーパー。

フロントエンドは完全にクライアントに含まれており、JSON または XML を返す REST または SOAP サービスを直接呼び出します。これで、表示用にドメイン オブジェクトを変換する際の問題は 100% 解決したようです!!!!

おそらく、上記の N 層アーキテクチャに対する明確な解決策がない理由は、それが明らかに間違っているからだと示唆する人もいます。

リンク

  1. http://raibledesigns.com/rd/entry/sofea_also_known_as_soui
  2. http://www.theserverside.com/news/thread.tss?thread_id=47213
  3. http://wisdomofganesh.blogspot.com/2007/10/life-above-service-tier.html

私の現在のプロジェクトでは、Data Transfer Objects を使用したやや時代遅れの N 層アーキテクチャを使用しています。アプリケーションは配布されておらず、配布されることもないため、DTO は不要です。DTOを使用することの1つの利点(IMOに値するものではありません)は、ビジネスメソッドのクリーンなインターフェースを強制することです-ビューコンポーネントは、疑似モデルのオブジェクトグラフを好きなようにトラバースできます-遅延初期化例外はできません投げられる。

私たちのアーキテクチャで見られるアーキテクチャ上の問題点の 1 つは、ビジネス インターフェイスが非常に複雑であることです。小さなビジネス インターフェースをすべてカプセル化するには、メタビジネス インターフェースが必要なようです。実際、これは、1 つのサービスが他の 3 つのサービスを呼び出してその作業を行う場合に発生します。

コントローラー (この場合、Struts 1.2 アクション クラス) は、最終的に、これらの超細粒度または粗粒度のビジネス コンポーネントの任意の組み合わせを呼び出します。残念なことに、ほとんどの場合、開発者は無意識のうちに、または怠惰に、さまざまなビジネス ロジックをコントローラー クラスにコーディングしています。これらの 300 行の Action メソッドの 1 つを見るたびに、私は叫びます!!!!

SOFEA アプローチは、よりクリーンなアプローチを提供しているようです。AJAX を使用すると、ブラウザーで実行されている Web アプリケーションでも、適切な MVC パターンを使用してフロント エンドをコーディングできます。これは、ユーザー (より動的な UI を提供すること) と開発者 (適切な MVC をコーディングできるようにすること) の両方にとって良いことです。

UI は、再利用可能なビジネス ロジックから完全に切り離されています。GUI は厚いですか、薄いですか。基本的に同じ方法でコーディングされます。

SOFEA / SOUI は私にとって初めてで、試したことはありませんが、最近読んだので、私の考えを共有したいと思いました。

于 2009-12-29T11:02:51.710 に答える
1

上記のアプローチは良さそうです。

しかし、UI-Beanを使用する必要があると思います。もちろん、このUI-Beanは事実上不変である必要があります。作成されたらすぐに、その状態(およびカプセル化されたドメインオブジェクト)を変更しないでください。

非常に単純化された例:


class UIBean {
  DomainObject o;

  public String getDescription(){
     return trimToSummaryText(o.getDescription());
  }

  private static String trimForSummaryText(){
     ....
  }
}

主な長所:

  • テンプレートコードは、よりクリーンで簡潔になる傾向があります。フロントエンド開発者はこれに満足するでしょう。
  • フロントエンド固有のヘルパーメソッドをドメインオブジェクトクラスに追加する傾向はありません。
  • 異なるドメインオブジェクトまたはview-beanのグループ化が可能です(ui-beanは複数のフィールドを持つことができます)。ここでは、リストのカプセル化が特に優れています。

はい、そのためにより多くのJavaクラスが含まれます。しかし、この抽象化レイヤーは、ほとんどの場合、Webアプリとページが大きくなるとすぐに問題ありません。

于 2009-12-28T20:19:25.610 に答える
0

質問が最後に回答されたのは約 1 年前ですが、おそらくその回答は誰かの役に立つと思われます。アーキテクチャによって全体的に概説されていますが、追加する唯一の詳細は次のとおりです。通常、上記の UiBean の代わりに、(ビューとサービスなど) 間でデータを渡すために、いわゆるDTO (データ転送オブジェクト) が使用されます。これらはプレーンな POJO であり、適切なフィールド/セッター/ゲッター。

Java EE 仕様の以前/初期のバージョンの 1 つで、「DTO」という用語が「ValueObject」と誤って混合されていましたが、目的は少し異なります。

お役に立てれば。

于 2013-05-08T09:55:28.070 に答える