これは、しばらくの間私を悩ませてきた問題です。私はこれらのパターンのいくつかについてまだかなり新しいので、用語のいずれかを間違って使用した場合は、私を許してください (そして私を修正してください)。
私の方法論
ゲームエンジンを作りました。私のゲーム エンジンのすべてのオブジェクトは、制御の反転を使用して依存関係を取得します。これらの依存関係はすべてプロトコルを実装しており、ブートストラップ フェーズ以外ではプロジェクト内で直接アクセスされることはありません。これらのオブジェクトを取得するために、サービス ロケーターの概念があります。サービス ロケーターの仕事は、特定のプロトコルに準拠するオブジェクトを見つけて返すことです。これはファクトリによく似ていますが、依存関係も処理する必要があります。
サービス ロケータにサービスを提供するために、サービス指定子と呼ばれるものがあります。サービス ロケータは、プロジェクト内のすべてのサービス指定子を認識しており、オブジェクトが要求されると、提供されたプロトコルに準拠するオブジェクトのインスタンスをそれぞれから取得しようとします。このオブジェクトは呼び出し元に返されます。このセットアップの素晴らしい点は、サービス指定子がサービス ロケーターについても認識しているため、依存関係がある場合は、サービス ロケーターにそれらの特定の依存関係を問い合わせるだけです。
例を挙げると、HighScoreManager というオブジェクトがあります。HighScoreManager は PHighScoreManager プロトコルを実装します。PHighScoreManager のインスタンスが必要な場合はいつでも、以下を呼び出して取得できます。
id<PHighScoreManager> highScoreManager = [ServiceLocator resolve: @protocol(PHighScoreManager)];
したがって、制御の反転。ただし、ほとんどの場合、これを行う必要さえありません。ほとんどのクラスはサービス指定子に配置されているためです。依存関係として PHighScoreManager が必要な場合は、サービス ロケータを通じて取得されます。したがって、私は制御の反転に対してフラットなアプローチをとっています。
私の問題
ゲーム エンジンのコードを共有したいので、スタティック ライブラリとしてコンパイルしました。これは他のすべての場合にうまく機能しますが、サービスロケーターでは少し扱いにくいようです. 問題は、一部のサービスがゲームごとに変更されることです。上記の例では、あるゲームのスコアは時間であり、別のゲームではポイントである可能性があります。したがって、HighScoreManager は、PScore オブジェクトの作成方法を指示する PHighScoreCreator のインスタンスに依存します。
PHighScoreCreator を HighScoreManager に提供するには、ゲームのサービス指定子が必要です。これを達成するために考えられる唯一の方法は、リフレクションの Cocoa バージョンを使用することでした。いろいろ調べてみたところ、クラスは NSBundle で発見できることがわかりましたが、現在のバンドルを取得する方法はないようです。したがって、サービス指定子を検索できるようにするには、ゲーム ロジックを独自のバンドルにコンパイルし、エンジンにこのバンドルを検索してロードさせる必要があります。これを行うには、エンジン コードとゲーム ロジック バンドルの両方を格納する 3 番目のプロジェクトを作成する必要がありますが、実際には、エンジンの静的ライブラリを使用するゲーム プロジェクトだけが必要です。
私の本当の質問
結局のところ、私の質問は
- Cocoa Touch で達成しようとしていることを行うためのより良い方法はありますか、または
- サービス指定子プロトコルに準拠するクラスをメイン バンドルから検出する方法はありますか?
質問を読んでくれてありがとう。
-らせん