这是一个困扰我一段时间的问题。我对其中一些模式还是很陌生,所以如果我错误地使用了任何术语,你必须原谅我(并纠正我)。
我的方法论
我创建了一个游戏引擎。我的游戏引擎中的所有对象都使用控制反转来获取依赖关系。这些依赖项都实现了协议,并且从不直接在项目中访问,除了在引导阶段之外。为了得到这些对象,我有了服务定位器的概念。服务定位器的工作是定位符合特定协议的对象并将其返回。它很像一个工厂,但它也应该处理依赖关系。
为了向服务定位器提供服务,我有我所说的服务说明符。服务定位器知道项目中的所有服务说明符,并且当请求一个对象时,尝试从它们中的每一个中获取符合所提供协议的对象实例。然后将该对象返回给调用者。这个设置很酷的是服务说明符也知道服务定位器,所以如果它有任何依赖关系,它只会向服务定位器询问那些特定的依赖关系。
举个例子,我有一个名为 HighScoreManager 的对象。HighScoreManager 实现了 PHighScoreManager 协议。在任何时候,如果需要 PHighScoreManager 的实例,可以通过调用来检索它:
id<PHighScoreManager> highScoreManager = [ServiceLocator resolve: @protocol(PHighScoreManager)];
因此,控制反转。然而,大多数时候甚至没有必要这样做,因为大多数类都位于服务说明符中,如果需要 PHighScoreManager 作为依赖项,则通过服务定位器检索它。因此,我有一个很好的平面控制反转方法。
我的问题
因为我希望共享游戏引擎中的代码,所以我将其编译为静态库。这对其他一切都非常有用,但服务定位器似乎有点棘手。问题是一些服务会随着游戏的变化而变化。在我上面的例子中,一场比赛中的得分可能是时间,而在另一场比赛中可能是积分。因此,HighScoreManager 依赖于 PHighScoreCreator 的一个实例,它告诉它如何创建一个 PScore 对象。
为了向 HighScoreManager 提供 PHighScoreCreator,我需要为我的游戏提供服务说明符。我能想到的唯一方法是使用 Cocoa 版本的反射。在挖掘之后,我发现类可以通过 NSBundle 发现,但似乎没有办法获得当前的包。因此,如果我希望能够搜索我的服务说明符,我将不得不将我的游戏逻辑编译到它自己的包中,然后让引擎搜索这个包并加载它。为了做到这一点,我必须创建第三个项目来容纳引擎代码和游戏逻辑包,而实际上我只想拥有一个使用引擎静态库的游戏项目。
我真正的问题
所以毕竟,我的问题是
- 有没有更好的方法来做我想要在 Cocoa Touch 中完成的事情,或者
- 有没有办法从主包中发现符合我的服务说明符协议的类?
感谢您的帮助并花时间阅读问题。
-螺旋状