3

Mac OS X用のBNRのCocoaプログラミング(第4版)の助けを借りてObjective-CとCocoaの学習を始めたばかりで、私はドキュメントベースのアプリケーションに取り組んでいます。私は、ドキュメントアーキテクチャに関するAppleの開発者向けドキュメントを読み、サブクラス化してサブクラスNSWindowControllerを上書きすることを選択しました。これを行う理由はいくつかあります。makeWindowControllersNSDocument

  • モデルロジック(NSDocumentサブクラス内)をビューロジック(サブクラス内)から分離しNSWindowControllerます。
  • ドキュメントウィンドウのタイトルをカスタマイズする(Appleの開発者向けドキュメントによると、不要な副作用なしにこれを行う適切な方法は、サブクラス化NSWindowControllerしてオーバーライドすることです。windowTitleForDocumentDisplayName:
  • Appleのドキュメントは、最も単純なアプリケーションを除くすべてのアプリケーションのサブクラス化を強く示唆しているようNSWindowControllerであり、私のものは間違いなく「単純」ではありません。

つまり、私のNSDocumentサブクラスはモデルコントローラーであり、私のNSWindowControllerサブクラスはビューコントローラーです。さらに、ビューとモデルはアプリケーションに依存せず、可能な限り再利用可能である必要があるため、アプリケーションの「作業」のほとんどはコントローラーオブジェクトで行われることを理解しています。ここで私の質問があります。これらの2つのタイプのコントローラーは、実際にこの「動作」を行うためにどのように相互作用するのでしょうか。

たとえば、スプレッドシートアプリケーションを作成していて、データの一部からグラフやグラフを作成するためのシートを表示するメニュー項目(またはツールバーボタン)が必要だとします。そのシートに、ユーザーはチャートまたはグラフの作成方法に関するさまざまなパラメーターとオプションを入力し、[OK](またはボタンが呼び出されたもの)をクリックします。

メニュー項目のアクション、ドキュメント(モデルコントローラー)またはウィンドウコントローラー(ビューコントローラー)に誰が応答する必要がありますか?シートを実際にロードして表示するタスクは明らかに「ビュー関連」のように見えるので、ウィンドウコントローラーに配置する必要があります。ただし、シートのコントローラーには、ユーザーに表示するモデル(Chartオブジェクト、または多分ChartInputs)が必要です。そのモデルはどこで作成され、シートコントローラーに渡されますか?ドキュメントを作成してメニュー項目に応答する必要がありますChartInputsモデルオブジェクト、それをウィンドウコントローラーに渡します。ウィンドウコントローラーはシートコントローラーを作成し、モデルオブジェクトを渡し、シートを表示しますか?または、ウィンドウコントローラーがメニュー項目に応答する場合は、新しいモデルオブジェクトを要求し(おそらく、ウィンドウコントローラーのコンストラクターへの依存性注入によって提供されるある種のファクトリを介して)、シートコントローラーの作成、モデルの受け渡し、および表示に進みます。シート?

ユーザーがシートに記入して[OK]をクリックした後はどうでしょうか。ユーザーの選択を処理し、実際にチャートを作成するために、コントロールをどこに戻す必要がありますか?ウィンドウコントローラー、ドキュメント、またはその両方ですか?ユーザーが[OK]をクリックした後、シートが閉じられる前に(何かが無効な場合)、ユーザーの入力を検証するロジックはどうですか?

4

1 に答える 1

6

まず、NSDocumentのウィンドウレス操作を検討してください。たとえば、NSDocumentクラスを共有するユーティリティアプリケーションを作成し、スクリプト、印刷、またはその他の操作のためにドキュメントを開きますが、プライマリドキュメントウィンドウは表示しません。そのアプリケーションで再利用されるNSDocumentクラスを想像してみてください。そして、不要なロジックをウィンドウコントローラーに配置します。このように、NSDocumentサブクラスは、主にドキュメントの状態に影響を与えるアクティビティを担当します。

これらは、モデルコントローラー(NSDocumentサブクラス)の責任です。

  • シリアル化と逆シリアル化
  • 読み込みと保存
  • ドキュメントの状態を操作する
  • 印刷ビューの管理とディスパッチ
  • 他の人による変更についてドキュメントを監視する
  • サポートするデータソース(ドキュメントモデルに影響を与えるソース)を更新し、必要に応じてモデルとドキュメントに変更を適用します
  • ドキュメントに関連するアクティビティログの管理
  • 元に戻るマネージャーを所有している
  • 重要なモデルオブジェクトをViewControllerに公開する
  • ウィンドウコントローラの作成
  • オブジェクトの作成または削除をトリガーする1つのプロパティへの変更など、一部の編集動作を容易にする

Core Dataを使用している場合、管理対象オブジェクトコンテキスト、永続ストアコーディネーター、および永続ストアは、モデルではなくモデルコントローラーの一部です。もちろん、管理対象オブジェクト自体はモデルの一部です。

これにより、これらの責任はモデルに委ねられます。

  • モデルオブジェクトを挿入、再配置、および削除するためのヘルパーメソッド
  • モデルの特定の部分にアクセスするためのヘルパーメソッド
  • データ検証
  • さまざまな形式でモデルを文字列にレンダリングする
  • 自分自身のシリアル化と逆シリアル化
  • あるプロパティへの変更が他のプロパティへの変更をトリガーするなど、一部の編集動作を容易にする

一方、これらはビューコントローラの責任です。

  • ビューを操作してモデルとの同期を維持する
  • ビューを操作して、ドキュメントの状態との同期を維持します
  • モデルオブジェクトを追加または削除するボタンなど、ローカライズされたアクションへの応答
  • 補助ビューを提示し、それらのビューでの入力に応答する
  • テーブルビューで選択された行など、UIでの選択によって影響を受けるディスパッチングアクション
  • 編集中に使用される、ドキュメント自体に関係のない補助コントローラーの管理(Webサービスデータなど)
  • ビューオブジェクトのデータソースとして機能

Cocoaバインディングを使用している場合、バインディングもViewControllerの一部です。

この設計により、ビューコントローラーとモデルコントローラーの間で責任が合理的に分離されます。ただし、どちらもビューとモデルの間にあります。これはモジュール性を生み出しますが、デカップリングは生み出しません。

ウィンドウレス操作を検討しましたが、経験的にこのデザインパターンにたどり着きました。類似したコードを組み合わせて、場違いに感じたコードを分離することでした。他の人がこれを行う方法について賛成または反対の権威ある情報源または参考文献を投稿するかどうか私は興味があります。


あなたの例を取り上げるために、私はこのデザインを提案します:

  1. EditorWindowControllerは、ChartParametersオブジェクトを作成し、ドキュメントのモデルへの参照を提供します。

    [[ChartParameters alloc] initWithWorkbook:self.document.workbook]
    
  2. EditorWindowControllerは、おそらく独自のNewChartViewControllerを持つ新しいチャートビューを設定します。ChartParametersとドキュメントオブジェクトをNewChartViewControllerに渡し、ウィンドウを表示します。

  3. ChartParametersオブジェクトは、ユーザーの選択を検証する役割を果たします。NewChartViewControllerは、検証結果との同期を維持するためにビューを操作する必要があります。(ユーザーにミスをさせないでください。入力を検証するために最後まで待たないでください。)

  4. ビューが終了すると、NewChartViewControllerは、指定されたパラメーターを使用して新しいグラフを作成するようにモデルに要求します。

    [self.document.workbook addChartWithParameters:self.chartParameters]
    

まだチャートになっていないオブジェクトをドキュメントの一部にしたい場合は、代わりに次のようにすることができます。

  1. EditorWindowControllerは、ドキュメントモデルに新しいチャートオブジェクトを作成するように要求します。

    Chart *newChart = [self.document.workbook addChart]
    
  2. 新しいチャートには、表示の準備ができていないことを示すフラグが設定されている必要があります。

  3. EditorWindowControllerは、NewChartViewControllerを設定し、チャートを渡し、ウィンドウを表示します。

  4. Chartオブジェクトはユーザーの選択を検証し、NewChartViewControllerはビューの同期を維持します。

  5. 終了したら、チャートに表示の準備ができていることを伝えます。または、ユーザーがキャンセルした場合は、削除します。

これらの設計のいずれにおいても、NewChartViewControllerは、特定のタスク用にローカライズされた、モデルコントローラーとビューコントローラーの1つです。

于 2013-01-10T18:41:20.157 に答える