4

私はOOを信じていますが、「OO準拠」のためだけに不適切な設計/実装を使用する必要があるほどではありません。

では、Servet/EJB/DataContainer レイヤード アーキテクチャを処理する方法は次のとおりです。

  • サーブレットはリクエストを受け取り、「ビジネス レイヤー」を呼び出します (セッション EJB など)。
  • ビジネス層は、データベースから DataContainers を見つけ、それらを操作してビジネス ロジックを実装します。
  • DataContainers には実際のコードは含まれず、データベースに対応する get/set のみが含まれます。

このアプローチには魅力があります。DataContainers は何をするかが明確で、データがどこから来るかを非常に簡単に知ることができます。

オブジェクト指向ではないことは別として、これにより、名前を付けたり整理したりするのが難しい不明確なビジネス層クラスが発生します。

もっと「オブジェクト指向」になろうとしていたとしても(たとえば、これらのメソッドのいくつかを DataConatiners に入れるなど)、これらの操作のいくつかは複数のデータ セットに対して動作します。

DataContainers をビジネス ロジックで汚染することなく、ビジネス レイヤーが混乱を招くような手続き型にならないようにするにはどうすればよいでしょうか?

class UserServlet {
  handleRequest() {
    String id = request.get("id");
    String name = request.get("name");
    if (UserBizLayer.updateUserName(id,name))
      response.setStatus(OK);
    else
      response.setStatus(BAD_REQUEST);
  }
}

class UseBizLayer {
    updateUserName(String id, String name) {
        long key = toLong(id);
        user = userDAO.find(key);
        if user == null
            return false;
        if (!validateUserName(name))
            return false;
        user.setName(name);
        userDAO.update(user);
        return true;
    }

    validateUserName(String name) {
        // do some validations and return
    }
}

class User {
    long key;
    String name;
    String email;

    // imagine getters/setters here
}
  • validateUserName名前のみで動作するため、ユーザーは必要ありません。別のクラスに入る可能性があると思いますが、別の手続き型「uti」型クラスがあります
  • データ構造を永続化戦略から分離することに価値があるため、ユーザーに永続化メソッドは必要ありません。
  • 他の場所でそのロジックを再利用する必要があるかもしれないので、サーブレットにビジネス ロジックは必要ありません。
  • User クラスにあまりにも多くのことを引き込み、ビジネス ロジックの再利用を困難にし、ユーザーを永続化戦略と結びつけるため、User にビジネス ロジックは必要ありません。

この例がそれほど悪くないことはわかっていますが、10 個の DataContainers と 20 個の BizLayer オブジェクトがそれぞれいくつかのメソッドを持っていると想像してください。これらの操作の一部が、特定のデータ コンテナーに「集中」していないことを想像してください。

これが手続き上の混乱にならないようにするにはどうすればよいでしょうか。

4

6 に答える 6

3

したがって、これに関する私の考えをいくつかの箇条書きで説明します。

  1. Java EE システムでは、ある時点で Java EE の配管に対処する必要があるようです。配管は常に OO の概念から恩恵を受けるとは限りませんが、少しの創造性と作業によって確実に恩恵を受けることができます。たとえば、AbstractFactory などを利用して、このインフラストラクチャを可能な限り共通化することができます。
  2. あなたが調べていることの多くは、ドメイン駆動設計と呼ばれる Eric Evans の優れた本で議論されています。彼はドメインの知識を表現し、それをサポートする技術インフラストラクチャを扱うという問題に対処しているので、それを見ることを強くお勧めします.
  3. DDD の一部を読んで GROKD したので、技術インフラストラクチャをリポジトリにカプセル化しました。リポジトリはすべて、セッション EJB に基づく永続化の戦略を使用するように作成されます。セッション EJBS と対話する方法を知っているデフォルトの実装を作成します。これを機能させるには、少し規則を追加し、インターフェイスでその規則/契約を指定する必要があります。リポジトリはすべての CRUD を実行し、絶対に必要な場合にのみそれ以上のことを実行する必要があります。「私の DAOS は私のリポジトリです」と言われたら、私は同意します。
  4. では、これを続けることに。UseBizLayer で表現される作業単位をカプセル化する何かが必要です。このレベルでは、すべてトランザクション スクリプトになるコードの記述に行き詰まっているという性質があると思います。責任と状態の分離を作成しています。これは通常、Java EE システム内でデフォルトのアーキテクチャとして行われている方法です。しかし、それはオブジェクト指向ではありません。モデルを調査して、少なくとも BizClasses に記述されているいくつかの動作を共通化できるかどうかを確認します。
  5. 私が以前に使用した別のアプローチは、BizLayer クラスを取り除き、ドメインからの呼び出しを操作を実行している実際のリポジトリ/DAO にプロキシすることです。ただし、これにはインフラストラクチャの構築への投資が必要になる場合があります。しかし、Spring のようなフレームワークや、いくつかの AOP コンセプトを使用してこれをうまく機能させ、必要なカスタム インフラストラクチャの量を削減することで、多くのことを行うことができます。
于 2008-09-30T15:30:44.327 に答える
1

クラスとオブジェクトを実装しているので、どのようにレイヤー化するかに関係なく、ソリューションはオブジェクト指向になります。状況やニーズによっては、うまく構造化されていない可能性があります。;-)

特定の質問に関しては、すべての User が有効な名前を持ちたいため、 validateUserName が User クラスに属することが理にかなっている場合があります。または、他のものに同じ検証規則を使用する名前があると仮定して、検証ユーティリティ クラスを作成することもできます。メールも同様です。これらを NameValidator クラスと EmailValidator クラスに分割できます。これは、頻繁に使用される場合に優れたソリューションとなります。また、ユーティリティ クラス メソッドを呼び出したばかりの User オブジェクトに validateUserName 関数を提供することもできます。これらはすべて有効なソリューションです。

OOD/OOP の大きな喜びの 1 つは、設計が正しければ、それが正しかったことがわかるということです。なぜなら、以前はできなかった多くのことがモデルから外れてしまうからです。

この場合、NameValidator クラスと EmailValidator クラスを作成します。これは、他のエンティティが将来名前と電子メール アドレスを持つ可能性が高いためですが、User クラスに validateName 関数と validateEmailAddress 関数を提供します。使用するオブジェクト。

残りの「望まない」箇条書きは正しいです。これらは適切なレイヤリングに必要なだけでなく、クリーンな OO 設計にも必要です。

階層化と OO は、レイヤー間の関心の分離に基づいて密接に連携します。あなたは正しい考えを持っていると思いますが、提示されている一般的な検証にはいくつかのユーティリティクラスが必要になります

于 2008-09-30T15:14:30.980 に答える
1

コンピューターがなかったら、これらのタスクがどのように実行されるかを考えて、そのようにシステムをモデル化してください。

簡単な例...クライアントはフォームに記入してウィジェットをリクエストし、それを従業員に渡します。従業員はクライアントの身元を確認し、フォームを処理し、ウィジェットを取得し、ウィジェットとトランザクションの記録をクライアントに渡し、保持します会社のどこかに取引の記録。

クライアントはデータを保存しますか? いいえ、従業員が行います。従業員がクライアント データを保存するとき、どのような役割を果たしますか? クライアントレコードキーパー.

フォームは正しく記入されていることを確認していますか? いいえ、従業員が行います。彼がそれをしているときに、従業員はどのような役割を果たしていますか? フォーム プロセッサ。

クライアントにウィジェットを提供するのは誰ですか? ウィジェット配布者として働く従業員

等々...

これを Java EE 実装にプッシュするには...

サーブレットはクライアントに代わって動作し、フォームに記入 (HTTP 要求からデータを取得して適切な Java オブジェクトを作成) し、それを適切な従業員 (EJB) に渡します。 . リクエストの処理中に、EJB は、さまざまなタスクに特化した別の EJB にリクエストを渡す必要がある場合があります。その一部には、ストレージ (データ層) との間での情報のアクセス/書き込みが含まれます。オブジェクトが相互に通信する方法と、データ レイヤーがストレージと通信する方法の詳細だけを、アナロジーに直接マッピングする必要はありません。

于 2008-09-30T15:15:11.573 に答える
0

私自身も同じ思いをしたことがあります。

従来の MVC で最も重要なことは、View を Model および Controller 部分から分離することです。モデル オブジェクトが肥大化する可能性があるため、コントローラーとモデルを分離することをお勧めします。


public class UserModel extends DatabaseModel implements XMLable, CRUDdy, Serializable, Fooable, Barloney, Baznatchy, Wibbling, Validating {
  // member fields
  // getters and setters
  // 100 interface methods
}

上記のインターフェイスの多くに対して個別のコントローラー (またはパターン全体) を使用できますが、そうです、本質的に手続き型ですが、最近ではそれが機能していると思います。あるいは、いくつかのインターフェースが同じことを行っていることを認識することができます (CRUDdy - データベースのストレージと検索、Serializable - バイナリ形式と同じ、XMLable、XML と同じ)。したがって、これを処理する単一のシステムを作成する必要があります。各潜在的なバックエンドは、システムが処理する個別の実装です。神様、それは本当にひどい書き方です。

たぶん、「コクラス」のようなものがあり、コントローラーの実装用に個別のソースファイルを用意して、それらが動作するモデルクラスのメンバーであるかのように動作します。

ビジネス ルールに関しては、複数のモデルを同時に処理することが多いため、それらを分離する必要があります。

于 2008-09-30T15:17:36.963 に答える
0

これは「関心の分離」についての質問だと思います。レイヤード アーキテクチャに関しては、正しい方向に進んでいるように見えますが、同じことをもっと行う必要があるかもしれません。つまり、Java EE レイヤー内にアーキテクチャ レイヤーを作成しますか?

DataContainer は、Data Transfer Objects (DTO) パターンによく似ています。

現代の OO 設計には多数の小さなクラスがあり、それぞれが少数の "友達" に関連しています (たとえば、コンポジションを介して)。これにより、実際に慣れているよりもはるかに多くのクラスと Java ボイラープレートが生成される可能性がありますが、より階層化され、単体テストと保守が容易な設計につながるはずです。

(質問には+1、レイヤー化の権利があることがわかったときの答えには+1)

于 2009-10-14T21:43:24.707 に答える
-1

大雑把に言えば、「私たちは望んでいない」セクションは行かなければなりません。それを正しくしたいのか、それともそのままにしておきたいのか。必要なときにクラスを作成しないことには意味がありません。「たくさんあります」は悪い言い訳です。

実際、すべての内部クラスを公開するの良くありませんが、私の経験では、概念 (つまり、ユーザー、ID、データベースの概念など) ごとにクラスを作成すると常に役立ちます。

それに加えて、Facade パターンは、よく整理されたクリーンなインターフェイスの背後に隠されている BizRules クラスの負荷の存在を解決するためのものではないでしょうか?

于 2008-09-30T14:59:23.343 に答える