在这种情况下,我已经成功引入(重复使用)有时会多层的“上下文”一词。
这意味着一个单例,即“全局”对象存储,可以从中请求这些类型的对象。需要它们的代码包括商店的标题,并使用全局函数获取其对象实例(例如现在的利率提供者)。
商店可能是:
- 严格类型化:包括所有服务类型的标头,因此您可以创建类型化访问器,例如InterestRate getCurrentInterestRate();。
- 或通用:Object getObject(enum obType); 并且仅使用新种类(obtypeCurrentInterestRate)扩展obType枚举。
系统越大,后一种解决方案就越有用,因为使用错误枚举的风险很小。另一方面,对于允许前向类型声明的语言,我认为您可以使用类型化访问器而无需在商店中包含所有标头。
还有一点需要注意:您可能具有相同对象类型的多个实例,以用于不同用途,例如有时GUI和打印输出,全局和会话级日志等使用不同的Language值,因此枚举/访问者名称不应反映实际类型,但是所请求实例的角色(CurrentInterestRate)。
在商店实现中,您必须管理上下文级别和上下文实例集合。一个简单的示例是Web服务,其中具有全局上下文(该对象的所有请求的一个实例-在拥有服务器场时有问题),以及每个Web会话的上下文。您还可以为每个用户提供上下文,这些用户可能具有多个并行的会话等。对于多台服务器,您应该为此类事情使用一种分布式缓存。
当请求进入时,您可以确定请求的对象位于哪个上下文级别,并获取该调用的上下文。如果对象在那里,则将其发送回;如果不是,则在该上下文级别创建并存储它,然后将其返回。当然,同步创建部分(并将其发布到分布式缓存)。创建可以是可配置的类似于插件的方式,最好使用允许通过其类名称(Java,Objective C,...)创建对象实例的语言,但是您也可以使用具有工厂功能的可插入库在C中执行此操作。
旁注:调用者不应对自己的上下文以及所请求对象的上下文级别了解太多。原因:1:通过使用这些参数很容易犯错误(或“聪明的把戏”);2:所请求的上下文级别以后可能会更改。我主要将上下文信息连接到线程,因此对象存储库中的信息没有请求中的额外参数。
另一方面,请求可能包含实例的提示:例如获取特定日期的利率。它应具有相同的“全局”访问权限,但要根据日期使用多个实例(并在费率变化之间将不同的日期值引入同一实例),因此建议向请求添加“提示”对象,实例工厂而不是商店;以及工厂使用的keyForHint。我刚才提到,您可以稍后添加这些功能。
就您的情况而言,这是一种矫(过正(在全局级别上仅提供一个对象),但是对于现在很小而又简单的额外代码,您将获得一种机制,可以满足进一步甚至更复杂的需求。
另一个好消息:如果您使用Java,则无需过多考虑即可从Spring获得此服务,我只是想详细解释一下。