web-dev-qa-db-ja.com

効率を維持しながらユーザーインターフェースをビジネスロジックから分離するにはどうすればよいですか?

コンボボックス上の10個の異なるオブジェクトを表すフォームを表示したいとします。たとえば、ユーザーに、トマトが含まれている10種類のハンバーガーの中から1つを選んでもらいたいとします。

UIとロジックを分離したいので、コンボボックスに表示するには、ハンバーガーの文字列表現をフォームに渡す必要があります。それ以外の場合、UIはオブジェクトフィールドを掘り下げる必要があります。次に、ユーザーはコンボボックスからハンバーガーを選び、それをコントローラーに送信します。これで、コントローラはフォームで使用されている文字列表現(IDの場合もあるか?)に基づいて、再度ハンバーグを見つける必要があります。

それは信じられないほど非効率ではありませんか?選択したいオブジェクトがすでにあります。オブジェクト全体をフォームに送信してから特定のオブジェクトを返した場合、フォームはすでにそのオブジェクトへの参照を返しているため、後でそれを再検索する必要はありません。

さらに、私が間違っていて、実際にオブジェクト全体をフォームに送信する必要がある場合、ロジックからUIをどのように分離できますか?

20
Uri

まず第一に、あなたが提供した例は信じられないほど非効率的ではありません。少しだけ非効率的です。その非効率性は知覚可能なレベルを下回っています。しかし、いずれにしても、質問に移りましょう。

私が理解している方法では、UIとロジックの分離について話すとき、密結合の回避を意味します

カップリングを閉じるは、UIがロジックを認識(および呼び出し)し、ロジックがUIを認識(および呼び出し)する状況を指します。密結合を回避するために、結合を完全に廃止する必要はありません。 (それは、それらの間のインターフェースを最小公分母の文字列インターフェースに解体することによって目指しているようです。)行う必要があるのは疎結合

疎結合は、AがBを認識しているが、BはAを認識していないことを意味します。つまり、関係する2つのパーティはclientserverロール。クライアントはサーバーを認識していますが、サーバーはクライアントを認識していません。

UIとロジックの場合、これを整理する最良の方法は、ロジックをサーバー、UIをクライアントと見なすことです。したがって、UIはロジック用に構築され、ロジックの知識を持ち、ロジックを呼び出しますが、ロジックはUIについて何も認識せず、受け取ったリクエストに応答するだけです。 (そして、これらのリクエストはたまたまUIからのものですが、ロジックはそれを知りません。)

より実用的に言えば、ロジックのソースコードファイル内のどこにも、UIファイルを参照するinclude/import/usingステートメントがあってはなりませんが、UIのソースコードファイルはinclude/import/usingでいっぱいになります。 Logicファイルを参照するステートメント。

したがって、あなたのケースに戻るために、コンボボックスを埋めるUIコードがハンバーガークラスを知っているという事実には絶対に何も問題はありません。ハンバーガークラスがコンボボックスについて何か知っていたら問題があります。

ちなみに、この設計では、このようなシステムに期待する別のことが可能になります。ロジックに必要な数のさまざまなUIを接続でき、すべてが引き続き機能するはずです。

36
Mike Nakis

モデル、ビュー、コントローラの各ピースを分離する必要がありますが、(たとえば)コントローラとビューの間でモデルオブジェクトを渡すことができない理由はありません。

したがって、あなたの場合、Hamburgerオブジェクトはモデルの一部になります。次に、コントローラーを使用して、必要なHamburgersのリストをフェッチし、それらのオブジェクトをビュー(コンボボックス)に渡して表示します。ユーザーがどのハンバーガーを選択したら、Hamburgerオブジェクトをコントローラーに再度渡して処理することができます。

ポイントは、「fetch Hamburgers」ロジックと「process Hamburger」ロジックをハンバーガーの実際の表示とは別に単体テストできることです。

5
Dean Harding