我的应用程序存储文件,您可以选择将文件存储在您自己的服务器上或使用S3。
我定义了一个界面:
interface FileStorage {
}
然后我有2个实现,S3FileStorage
和LocalFileStorage
。
在控制面板中,管理员选择他们想要的FileStorage
方法,并将此值存储在SiteConfiguration
对象中。
由于在应用程序运行时可以更改FileStorage
设置,您是否仍然使用spring的DI来执行此操作?
或者你会在你的代码中执行此操作:
FileStorage fs = null;
switch(siteConfig.FileStorageMethod)
case FileStorageMethod.S3:
fs = new S3FileStorage();
case FileStorageMethod.Local:
fs = new LocalFileStorage();
哪一个更有意义?
我相信你可以在运行时使用DI和弹簧,但我现在还没有读过很多。
答案 0 :(得分:3)
我会注入一个工厂,让客户在运行时从它那里请求实际的服务。这将使您的客户与实际的工厂实现分离,因此您也可以进行多个工厂实施,例如,进行测试。
您也可以使用某种代理对象,其后面有几种策略而不是工厂,但如果无法提供来自一个客户端的调用序列(如打开,写入,关闭文件存储),则会导致问题通过不同的实现。
答案 1 :(得分:2)
我仍然会在这里使用依赖注入。如果可以在运行时更改它,则应使用setter注入而不是构造函数注入来注入它。使用任何依赖注入的好处是,您可以轻松添加接口的新实现,而无需更改实际代码。
答案 2 :(得分:1)
DI毫无疑问。或者您希望在创建/更新/删除实现时增强工厂代码? IMO,如果您正在编程接口,那么您不应该引导您的实现,但实际上会发生很多层。
此外,DI不是Spring等人的同义词。它就像包含一个带有抽象接口作为参数的构造函数一样简单,即public FileApp(FileStorage fs) { }
。
仅供参考,另一种可能性是proxy。