ビジネスロジックがビューに忍び寄らないようにすることは可能ですか?


31

私は過去3年間、個人および職場の両方でいくつかのWebアプリケーションプロジェクトを開発してきましたが、少なくとも一部のビジネスロジックがアプリケーションのビューレイヤーで終了する可能性があるかどうかはわかりません。

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

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

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


2
MVC派生MVPおよびMVVM(en.wikipedia.org/wiki/Model_View_Presenterおよびen.wikipedia.org/wiki/Model_View_ViewModelを参照)をご覧ください。それらはあなたが探しているものかもしれません。
ドックブラウン


2
ビューは、データとロジックの外部から見える表示です。ビューがビジネスロジックを表示しないことはできません。または、ビューにコードを含めるべきではないと言っていますか?もちろん、HTMLのみのビューを作成できます。
BobDalgleish

テンプレートアニメーションを調べることもできます。これはおそらくビューレイヤーからすべてのロジックを根絶するわけではありませんが、物事の少し良い分離につながるはずです。
ポール

ビューデータがモデルを汚染する方が良いのか、ビジネスロジックに関連するビューロジックをビューに含める方が良いのか、という疑問があります。それはより現実的なシナリオです。あなたの質問は本質的にモデルの汚染を提唱し、あなたが求めていることを達成するための唯一の方法であるビューをサポートすることです。
ダンク

回答:


22

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

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

理論的には、はい、私たちがビジネスロジックとして定義するものに依存します。実際には、厳密な分離ははるかに難しくなり、望ましくない場合もあります。

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

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

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


2
The best conceptual location may not be the best location for other reasons:ブラボー!!
マグノC

8

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

controller->OptionXChanged()

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

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

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


+1。OPの些細な問題は、通常、非自明なアプリケーションでこのように処理される
dev_feed

このロジックをコントローラーに配置すると、2つの問題があります。1)単体テストが複雑になり、同じデータの複数のビューをサポートすることができなくなります。
ケビンクライン

4

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

「ビュー」の観点からは、システムにInfoYまたはInfoZのみを提供しています。UI実装がオペレータの選択に基づいて動的更新を実行している(つまり、InfoYまたはInfoZを有効にしている)だけでは、機能がビジネスロジックになりません。それは実際にビューの実装ロジックです。オペレータに、InfoYまたはInfoZを入力する選択肢を与えるだけで、すべてを有効にすることはできませんでした。その文脈では、あなたはまだそれをビジネスロジックと考えますか?そうでない場合は、情報フィールドの動的な有効化/無効化にも同じことが当てはまります。

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

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


1

私はこの方法で作業します(Struts2 + Hibernate):

My Struts Actionsは、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";
}

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

したがって、サービス、リポジトリ、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

ほとんどの場合、「ユーザーがオプション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パターンのモデルは、(通常)ビジネスオブジェクトモデルではありません。UI状態の単なるモデルです。デスクトップアプリケーションでは、複数のビジネスモデルへの参照を保持できます。Web 2.0アプリケーションでは、UI状態を保持し、AJAXを介してサーバーと通信するJavascriptクラスです。ほとんどのUIバグが見つかる場所であるため、UI状態モデルのハンドオフユニットテストを作成できることが非常に重要です。ビューとコントローラーは非常に細いコネクターにする必要があります。


1
MVCの定義があなたが信じているものに要約されると思います。このバージョンは、MVCの非常に厳密な解釈に確実に準拠しています。問題は、この厳密な解釈が実際の生活で有用または保守可能なシステムを提供することはめったにないということです。理由は、モデルを変更する必要がある新しいUI要素/方法を思い付くたびにだからです。その後、モデルは、UIにのみ関連する無用なプロパティで混雑します。これらは、ビルドしようとしているアプリケーションとは関係ありませんが、オペレーターにデータを提示する方法とのみ関係があります。悪い!
ダンク

ケビンは、コメント欄に回答を入力してください。返信が簡単になります。仰るとおりです。どんな種類の構造もなしにインターフェース(UI)情報を維持することはできませんが、「モデル」の命名法は紛らわしいかもしれません。@Dunkが話していることを簡単に行えるように、UIを別の交換可能なパッケージで管理することを好みます。私の答えをご覧ください。
マグノC

@MagnoC:追加されたテキストが答えを改善すると思ったので、私はダンクへの応答で彼の答えを編集しました。それがサイトの目的です:質問と回答。モデルは非常に一般的な用語であり、MVCパターンでは「UI状態モデル」を意味します。
ケビンクライン

0

ビジネスロジックはに似て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

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

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

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

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.