bwahaの書き込み:
著者は、MVCデザインの例としてwxPythonのmvctree.pyを参照しています。しかし、私はまだあまりにも緑なので、その特定の例は複雑すぎて、著者が推奨している分離を理解していません。
MVCは、懸念事項の分離に関するものです。
モデルは、プログラムのデータ(プライベートデータとクライアントデータの両方)の管理を担当します。View / Controllerは、プログラムのクライアントデータと対話する手段を外部に提供する役割を果たします。
モデルは、プログラムの他の部分がモデルと対話できるようにする内部インターフェイス(API)を提供します。ビュー/コントローラーは、外部インターフェイス(GUI / CLI / Webフォーム/高レベルIPC /など)を提供し、プログラムのすべてが通信できるようにします。
モデルは、プログラムのデータの整合性を維持する責任があります。データが破損した場合、誰でもゲームオーバーになるからです。ビュー/コントローラーは、UIの整合性を維持し、すべてのテキストビューが最新の値を表示していることを確認し、現在のフォーカスに適用されないメニュー項目を無効にするなどの責任を負います。
モデルにはビュー/コントローラーコードが含まれていません。GUIウィジェットクラス、ダイアログボックスのレイアウトまたはユーザー入力を受け取るためのコードはありません。ビュー/コントローラーにはモデルコードが含まれていません。URLを検証したりSQLクエリを実行したりするコードはなく、元の状態もありません。ウィジェットが保持するデータは表示専用であり、モデルに保存されている真のデータを単に反映したものです。
さて、ここに真のMVCデザインのテストがあります。View/ Controllerが接続されていなくても、プログラムは本質的に完全に機能するはずです。OK、外の世界はその形式でそれとやり取りするのに苦労しますが、適切なModel APIの呪文を知っている限り、プログラムは通常通りデータを保持して操作します。
なぜこれが可能ですか?簡単な答えは、モデルレイヤーとビュー/コントローラーレイヤー間の結合が低いためです。ただし、これは完全な話ではありません。MVCパターン全体の鍵となるのは、それらの接続の方向です。すべての命令は、ビュー/コントローラーからモデルに流れます。モデルは、View / Controllerに何をすべきかを決して伝えません。
どうして?MVCでは、ビュー/コントローラーはモデル(特に、モデルのAPI)について少し知ることはできますが、モデルはビュー/コントローラーについて何も知ることはできません。
どうして?MVCは懸念事項を明確に分離するためのものだからです。
どうして?プログラムの複雑さが制御不能になり、開発者であるあなたをその下に埋もれないようにするため。プログラムが大きいほど、そのプログラムのコンポーネントの数が多くなります。そして、それらのコンポーネント間に多くの接続が存在するほど、開発者が個々のコンポーネントを維持/拡張/交換したり、システム全体の動作を追うことさえ難しくなります。これを自問してみてください。プログラムの構造の図を見ると、木や猫のゆりかごを見るのが好きですか?MVCパターンは、循環接続を許可しないことで後者を回避します。BはAに接続できますが、AはBに接続できません。この場合、Aはモデルで、Bはビュー/コントローラーです。
ところで、あなたが鋭いなら、あなたはちょうど説明された「一方向」の制限に問題があることに気付くでしょう:モデルが許可されていないときにモデルのユーザーデータの変更をモデルがビュー/コントローラーに通知する方法View / Controllerにメッセージを送信してもかまいませんか?しかし、心配しないでください。これには解決策があります。最初は少し回り道をしているように見えても、かなりきれいです。それについてはすぐに説明します。
実際には、View / Controllerオブジェクトは、モデルのAPIを介して、1。モデルに何かを行うように指示する(コマンドを実行する)、2。モデルにそれを与えるように指示する(データを返す)ことができます。ビュー/コントローラーレイヤーは、命令をモデルレイヤーに
プッシュし、モデルレイヤーから情報を取得します。
そして、最初のMyCoolListControlの例がうまくいかないのは、そのクラスのAPIに情報をプッシュ
する必要があるためです。そのため、レイヤー間の双方向のカップリングに戻り、MVCルールに違反し、すぐにダンプします猫のゆりかごのアーキテクチャは、そもそも(おそらく)回避しようとしていました。
代わりに、MyCoolListControlクラスはフローを使用して、必要なときに必要なデータを下のレイヤーからプルする必要があります。リストウィジェットの場合、一般に、値の数を尋ねてから、それらの各項目を順番に尋ねることを意味します。これは、それを行うための最も単純で最もゆるい方法であり、したがって、存在する結合を最小限に抑えるためです。そして、ウィジェットが、たとえば、それらの値をアルファベット順に並べてユーザーに表示したい場合、それはその意味です。そしてその責任はもちろんです。
さて、先ほど示唆したように、最後の難問は、MVCベースのシステムでUIの表示をモデルの状態とどのように同期させるかということです。
問題は次のとおりです。多くのViewオブジェクトはステートフルです。たとえば、チェックボックスにチェックマークを付けたり、チェックを外したり、テキストフィールドに編集可能なテキストを含めることができます。ただし、MVCはすべてのユーザーデータをモデルレイヤーに保存するように指示しているため、表示目的で他のレイヤーが保持するデータ(チェックボックスの状態、テキストフィールドの現在のテキスト)は、そのプライマリモデルデータの補助コピーでなければなりません。ただし、モデルの状態が変更された場合、その状態のビューのコピーは正確でなくなるため、更新する必要があります。
しかし、どのように?MVCパターンは、モデルがその情報の新しいコピーをビューレイヤーにプッシュするのを防ぎます。ちなみに、ModelがViewにメッセージを送信して、状態が変わったことを伝えることさえできません。
よくほとんど。さて、モデルレイヤーは他のレイヤーと直接対話することは許可されていません。そのためには、それらのレイヤーについて何かを知っている必要があり、MVCルールがそれを妨げるからです。しかし、木が森に落ち、誰もそれを聞いていない場合、音がしますか?
答えは、通知システムをセットアップして、モデルレイヤーに、特に興味深いことを行ったことを誰にも告知できない場所を提供することです。他のレイヤーは、その通知システムを使用してリスナーをポストし、実際に興味のあるアナウンスをリッスンできます。モデルレイヤーは、誰がリッスンしているか(またはだれかがリッスンしている場合でも)を知る必要はありません。アナウンスを投稿し、それを忘れます。そして、もし誰かがその発表を聞いて、その後何かをしたい気がしたら-モデルに画面上の表示を更新できるように新しいデータを要求する-素晴らしい。モデルは、API定義の一部として送信する通知をリストするだけです。そして、他の誰かがその知識で何をするかは彼ら次第です。
MVCは保存され、誰もが幸せです。アプリケーションフレームワークは、組み込みの通知システムを提供する場合があります。そうでない場合は、独自のフレームワークを作成できます(「オブザーバーパターン」を参照)。
...
とにかく、それが役立つことを願っています。MVCの背後にある動機を理解すると、物事がそのように行われる理由は、一見、必要以上に複雑に見えても意味を持ち始めます。
乾杯、
持っている