web-dev-qa-db-ja.com

ビジネスロジックがビューに侵入しないようにすることは可能ですか?

私は過去3年間、個人および仕事の両方でいくつかのWebアプリケーションプロジェクト用に開発してきましたが、少なくともsomeビジネスロジックが可能にならないかどうかを理解できませんアプリケーションのビュー層。

ほとんどの場合、「ユーザーがオプションxを選択した場合、アプリケーションはyに情報を提供できるようにする必要があり、そうでない場合、ユーザーは情報zを提供する必要があります」のような問題があります。または、いくつかのAJAX操作を実行すると、モデルにいくつかの変更が適用されますが、ユーザーが明示的に要求するまで変更はコミットされません。これらは、私が遭遇した最も簡単な問題の一部であり、ビューで複雑なロジックを回避する方法を理解してください。

私がMVCについて説明した本のほとんどは、通常、サーバー上のデータを更新して表示するCRUD操作など、いくつかの非常に些細な例を紹介していますが、ほとんどのリッチアプリケーションではCRUDは当てはまりません。

ビジネスロジックがまったくないビューを実現することは可能ですか?

31
vdaras

ビジネスロジックがまったくないビューを実現することは可能ですか?

これは一見難しい答えの質問です。 (考えさせられる質問!)

理論的には、はい、ビジネスロジックとして定義する内容によって異なります。実際には、厳密な分離は非常に難しくなり、望ましくない場合さえあります。

関心事の分離は、ソフトウェアの構築について考える優れた方法です。これは、コードを配置する場所についてのアイデアを提供し、メンテナーにコードを探す場所についての良いアイデアを提供します。私は人間が心配を分離せずに実用的なソフトウェアを構築することは基本的に不可能だと主張します。これが必要です。

しかし、すべてのことと同様に、トレードオフがあります。他の理由により、最適な概念上の場所が最適な場所ではない場合があります。 Webサーバーに負荷がかかりすぎている可能性があるため、JavaScriptをWebページに追加して、サーバーに到達する前に簡単な入力エラーをキャッチします。これで、ビューにいくつかのビジネスロジックがあります。

ビュー自体は、ビジネスロジックなしでは価値がありません。また、暗黙的または明示的に使用および表示を効果的に行うために、ビューはその背後で行われているビジネスプロセスについてある程度の知識を持っています。私たちはその知識の量を制限することができ、その知識の一部を切り離すことができますが、実際的な考慮事項はしばしば懸念の分離を「壊す」ことを強制します。

22
JvR

私は通常これを行います:ユーザーがオプションxを選択した場合、ビューは

controller->OptionXChanged()

次に、コントローラーでビューのyを有効にします。

view->SetEnableInfoY(True) // suppose False=SetDisable

ビューは何も決定せずに何が起こるかをコントローラーに通知します。

8
Fil

あなたが説明する例が本当にビジネスロジックなのか疑問に思います。説明する例は、システムで実行できる操作です。ビューでビジネスロジックを実行しているように見えるのは、ユーザーに選択肢を提示する方法です。

「ビュー」の視点からは、システムにInfoYまたはInfoZを提供するだけです。 UI実装がオペレーターの選択に基づいていくつかの動的更新を行う(つまり、InfoYまたはInfoZを有効にする)だけでは、機能のビジネスロジックは作成されません。それは本当にビュー実装ロジックです。オペレーターに、有効にするもの全体を使用せずに、InfoYまたはInfoZを入力する選択肢を与えるだけで十分です。その文脈で、それをビジネスロジックと見なしますか?そうでない場合は、動的に情報フィールドを有効または無効にする場合にも同じことが当てはまります。

コミットの例も同様です。これらは、システムが正しく動作するために必要な2つの個別の操作です。ビューは、必要な機能を実行するために適切なアクションを開始できる必要があります。システムの使い方を知っているということは、ビジネスロジックがリークしているということですか?私は誰かがはいと言うかもしれない方法を見ることができますが、あなたがそのように信じるなら、現実はビジネスロジックを何かから分離するようなものはないというのが現実です。意味のあることを達成するためには、システムが何をしているか/どのように働いているかを知る必要があります。それ以外の場合は、考えられるすべてのMVCアプリケーションで機能する単一の汎用ビューおよびコントローラーを作成するのは簡単です。私たちが知っていることは不可能です。

結論として、私はあなたのビジネスロジックの定義は他の定義と同じではないと思います。

4
Dunk

私はこのように動作します(Struts2 + Hibernate):

私のStrutsアクションは、Webブラウザーでの情報の表示のみを担当します。考えていません。

ユーザー->アクション->サービス->リポジトリ->データアクセス

または:

見たい->見方->何をすべきか->入手方法->入手場所

したがって、最初のレイヤー(ビュー)には次のようなものがあります。

public String execute ()   {
    try {
        CourseService cs = new CourseService();
        Course course = cs.getCourse(idCourse);
    } catch (NotFoundException e) {
        setMessageText("Course not found.");
    } catch (Exception e) {

    }
    return "ok";
}

ご覧のとおり、私の「見方」は考えていません。特定のコースのサービス(コースの管理)を要求しています。そのサービスは、レポート、Seracheなどの多くのことを実行できます。結果は常にリストまたは特定のオブジェクトです(例のように)。サービスは実際のマシンであり、ルールを適用し、リポジトリにアクセスします(データを管理するため)。

したがって、サービス、リポジトリ、DAOSを別のライブラリに配置すると、テキストベースのプログラムや、何も変更されていないウィンドウベースのデスクトップシステムでも使用できます。

サービスは何をすべきかを知っていますが、どのように表示するかはわかりません。ビューは表示方法を知っていますが、何をすべきかわかりません。サービス/リポジトリと同じ:サービスはデータを送信および要求しますが、データの場所とその取得方法を認識していません。リポジトリは、生データを「構成」してオブジェクトを作成し、サービスが動作できるようにします。

しかし、リポジトリはデータベースについて何も知りません。データベースの種類(MySQL、PostgreSQLなど)はDAOに関係しています。

データベースを変更する必要があり、上位層に影響を与えてはならない場合は、DAOを変更できます。データ管理を更新する場合は、リポジトリを変更できますが、DAOと上位層に影響を与えないようにする必要があります。ロジックを変更したい場合はサービスを変更できますが、これは上下のレイヤーを混乱させてはなりません。

また、テクノロジー(Web、デスクトップ、テキスト)を含め、表示されているものは何でも変更できますが、これは以下のことを意味するものではありません。

ビジネスロジックはサービスです。しかし、これと対話する方法は表示することです。今表示するボタンは?ユーザーはこのリンクを見ることができますか?システムがコンソールベースのプログラムであると考えてください。間違ったユーザーが#> myprogram -CourseService -option=getCourse -idCourse=234を選択した場合に拒否するか、キーを押してこのコマンドを書き込むのを止める必要がありますか?

Webベースのシステム(Struts + JavaEE)での会話別のGUIコントローラーパッケージがあります。ビューアクションでは、ログに記録されたユーザーとクラスにボタン(または必要なインターフェイス要素)を提供します。

                <div id="userDetailSubBox">
                    <c:forEach var="actionButton" items="${actionButtons}" varStatus="id">
                        ${actionButton.buttonCode}
                    </c:forEach>
                </div>

そして

private List<ActionButton> actionButtons;

これをサービスから除外することを忘れないでください。これはVIEWのものです。 Strutsアクションに保持します。インターフェイスの相互作用は、実際のビジネスコードから完全に分離する必要があるため、システムを移植すると、不要になったものを簡単にカットできます。

1
Magno C

ほとんどの場合、「ユーザーがオプションxを選択した場合、アプリケーションはユーザーがyの情報を提供できるようにする必要があります。そうでない場合、ユーザーは情報zを提供する必要があります」

これはビューではなく、モデルのロジックです。 UIをサポートするために特別に作成された「ビューモデル」の場合もありますが、それでもモデルロジックです。制御シーケンスは次のとおりです。

  • コントローラーはビューイベントのハンドラーをアタッチします
  • ビューはモデルイベントのハンドラーをアタッチします
  • ユーザーはオプションXを選択します。
  • ビューはイベント「Option X Selected」を発生させます
  • コントローラはイベントを受け取り、model.selectOptionX()を呼び出します
  • モデルは「モデルの状態が変更されました」というイベントを発生させます
  • ビューはモデル変更イベントを受け取り、ビューを更新して新しい状態に一致させます:inputY.enable(model.yAllowed()); inputZ.enable(model.zAllowed());

UI View Controller Model |.checkbox X checked.> | | | | | .. X selected ...>| | | | |-----> set X ------->| | | | | | |< .............state changed ............| | | | | | |-------------- Get state --------------->| | | | | | |<----------- new state ------------------| | <-- UI updates ------|これは古典的なMVCパターンです。 UIとは別にモデルロジックを完全にテストすることが可能です。コントローラとビューは非常に薄く、テストが簡単です。

===ダンクに応じて===

UI MVCパターンのモデルは(通常)notビジネスオブジェクトモデルです。これは単なるUI状態のモデルです。デスクトップアプリケーションでは、複数のビジネスモデルへの参照を保持できます。 Web 2.0アプリケーションでは、UI状態を保持し、AJAXを介してサーバーに通信します。JavaScriptのクラスです。 UI状態モデル(ほとんどのUIバグが検出される場所です)ビューとコントローラーは非常に薄いコネクターである必要があります。

1
kevin cline

ユーザーがオプションxを選択した場合、アプリケーションはyに情報を提供できるようにする必要があります。そうでない場合、ユーザーは情報z "を提供する必要があります。

条件に基づく必要な値を持つ入力があります。ほとんどのGUI環境では、入力、特にタイミングを処理する方法について多くの選択肢があります。選択したオプション(この場合はx)を処理する必要があるため、コントローラーに送信します。ユーザーが入力フィールドを離れたときに送信します。彼らが別のオブジェクトをクリックするか、保存をクリックするまで待ちます。ビジネスロジックには関係ありません。いずれにしても、コントローラーは決定を下し、ビューに「yが必要」と伝える必要があります。

ビューがこれをどのように解釈または実装するかは、ビジネスロジックの観点からは重要ではありません。 yを必須フィールドにします。ポップアップを表示するか、大砲を撃ち落として、yと入力するか、頑固になるようにユーザーに伝え、貧しいユーザーがこれを理解するまで何もしないでください。

考えてみてください。これは、コントローラーが保存しようとし、データベースの必須フィールドに値を入力せず、純粋にデータベースエラーに応答していたために発生した可能性があります。ビューに関する限り、問題ではありません。

入力の必須または制限された値などは、多くの場所で処理できます。ビューでアドレス指定のみを行うと、複数のユーザーインターフェイスが存在する可能性がある場合、多くの開発者はこれを問題と見なします。これが、多くのユーザーインターフェイスやデータベースがなくてもビジネスロジックを作成およびテストできる理由です。あなたもウェブサイトを持っている必要はありません。

0
JeffO

ビジネスロジックはIf X then return InfoType.Yに似ており、UIはドメインから返された結果に基づいてフィールドを表示します。

// Controller method pseudocode
option changed routine

    get selected option

    get required info type from domain routine based on selected option

    display fields based on required info type

UIにビジネスロジックが必要な場合は、選択をドメインに委任します。 UIは単に決定に基づいて動作します。

0
Yorro