1

私は、ほぼ 1,000 の異なる種類のデータ項目 (ただし、100 未満の異なるデータ構造/クラス) を持つクロスプラットフォームの C++ データ モデルを開発しています。モデルからコントローラーへのメッセージ (つまり、一部のデータ項目が変更されたというコントローラーへの通知) を処理するために、boost:signals2 を使用することを考えています。これは、異なる OS プラットフォーム間で同じままである統一されたオブザーバー パターンを作成するのに役立つと思います。最初の実装は Mac OS / IOS で行われ、その後の UI は .net と unix で開発されました。

質問:

1) データモデルの観測を設定するには、コントローラーはどのタイプのオブジェクトをシグナル2オブジェクト/スロットに接続する必要がありますか? 観察される各データ項目のコントローラーに特定の関数/メソッド/セレクターが必要ですか? これらの関数は、C、C++、または Objective-C/C++ 関数である必要がありますか?

2) シグナルはどのレベルの粒度を持つべきですか? データの各項目は独自のものを持つべきですか? それとも、関連する構造/レコードのモデルの管理は、構造/レコードのタイプごとに単一のシグナルを維持する必要がありますか? たとえば、どのデータ項目が変更されたかについての情報を渡すために、アプリケーションの設定はすべての設定データに対して 1 つのシグナルを持つべきでしょうか?

3) シグナルを送信するプロセス (またはシグナルを受信するスロット) は、SEPARATE THREAD で実行する必要がありますか?

4) Cocoa には Key-Value Observing 用の独自のシステムがあることを理解しています。しかし、そのようなシステムは、モデルのシグナル 2 ベースのオブザーバー パラダイムと組み合わせるのに有利でしょうか? それとも単に冗長なのでしょうか?

アップデート:

実際の signal2 オブジェクト (オブザーバーではない) の「粒度」に関しては、ドキュメントごとに 1 つ、アプリケーション設定用に 1 つ持つことから始めるのが良いと思います。私のドキュメント データには既に「キー」の概念があるため、UI コンポーネントがモデル データの特定の項目に関連付けられている一般的な UI ケースを一般化できる可能性があります。

4

1 に答える 1

1

この質問には非常に多くの側面があるので、私ができることを取り上げます。

Objective-C と .NET で何かを観察できるようにしたいのはなぜですか?

なぜ第 4 世代言語でデータモデルを観察したいのを考えるのは有益だと思いますか? サブシステムを分離するだけでなく、場合によっては UI インターフェイス要素をデータ モデルに直接バインドすることもでき、コントローラーに大量のコードを記述する必要がなくなります。これは、.NET 上に構築された WPF アプリケーションと MacOSX 上の AppKit で可能です。iOS で UIKit を使用する機会は少なくなります。

メタモデル

最初に指摘すべき明白なことは、ターゲットにしたい 2 つの言語ランタイム (Objective-C と .NET) が、オブジェクトプロパティを中心に構築されたオブザーバー パターンの言語レベルの実装を提供することです。何千行もの定型コードを書かずにそれらを統合したい場合は、これも行いたいと思うでしょう。

これは、すべての C++ モデル クラスが、ジェネリック プロパティ メカニズムを提供するメタモデルから継承する必要があることを強く示唆しています。これで、それらを観察するためのメカニズムが完成します。

別の方法は、C++ で定型的なセッター/ゲッターを大量に生成し、.NET と Objective-C でそれらを利用するためにオブジェクトをバインドすることです。

アダプター

.NET と Objective-C の両方で、リフレクションを使用して汚れた作業を行う汎用アダプター クラスを設計します。Objective-C の場合、メソッドをオーバーライドしNSObjectて、プロパティ セットを転送したり、メッセージを基になるモデルのプロパティ メカニズムに取得したりしてこれを行います。.NET では、リフレクションを使用して、モデル内のプロパティに対応するプロパティをアダプターに挿入できると信じています。

【余談】IDL/ORM

メタモデルの上に構築されたデータ モデルを持っている時点で、何らかの IDL や ORM を使用して、非常に多数のモデル クラスを記述し、自動的に生成することをお勧めします。あなたが扱っている膨大な数のクラスもこれを示唆しています。

オブザーバーの粒度

粒度に関しては、どちらかを行うことができます。実際には、データモデルの変更方法と、UI がそれに反応する必要がある方法に依存します。Objective-C の KVO は、オブジェクトの名前付きプロパティの変更を中心に設計されていますが、オブザーバーが監視するすべてのオブジェクトとプロパティに対して単一のデリゲート メソッドを持っているという制限があります。ただし、これは Objective-C UI コンポーネントのみの問題です。
これと統合することは、C++ と Objective-C の間を橋渡しする値変更イベント用の大量のアダプタ メソッドを作成する場合を除いて、間違いなく価値があります。インターフェイスC++クラスを継承しますが、オブジェクトC++コンパイルユニットでのブリッジや厄介なキャストなしで、C++からオブジェクトCオブジェクトにメッセージを直接送信することはできません。
.NET を使用すると、中間のマネージ C++ レイヤーを使用して、あらゆる種類の同様の策略に入る可能性があります。

ねじ切り

複数のスレッドを使用してこれを行う唯一の適切な方法は、UI スレッドで処理するシグナルをキューに入れることです。結局のところ、別のスレッドでシグナルを生成する場合は、後で UI を更新するためにこれを行う必要があります。アプリのモデル部分とビュー/コントローラー部分に別のスレッドを使用すると、デッドロックのレシピのように聞こえます。また、シグナルのソースをデバッグするのも非常に難しくなります。シグナルが別のスレッドで長く消えてしまうからです。すべてを 1 つのスレッドにまとめておくと、生活がずっと楽になります。

于 2013-05-30T00:04:04.033 に答える