您可以將Guice集成到工廠中,但是您的代碼可能與本例中的代碼完全相同。
這實際上是那些不能輕易替換的工廠之一,因爲它必須包含解析出jsonSpec
的邏輯,並根據這個邏輯修改它返回的具體類型。比方說,工廠的稍微少簡化的版本是這樣的:
public class UserInfoFactory {
public UserInfo createFromJsonString(String jsonspec) {
if(getUserType(jsonSpec) == TWITTER) {
return new TwitterUserInfo(jsonSpec);
} else { /* ... */ }
}
private UserInfoType getUserType(String jsonSpec) { /* ... */ }
}
這邏輯有地方住,和你自己的UserInfoFactory
似乎是一個完美的家。但是,因爲您使用的是new
,所以您將無法注入任何TwitterUserInfo
的依賴關係或其依賴關係的依賴關係,並且是Guice很好地解決的問題類型。
您可以注入TwitterUserInfo
作爲Provider
,這將給你訪問到許多完全注入TwitterUserInfo
的對象,只要你願意:
public class UserInfoFactory {
@Inject Provider<TwitterUserInfo> twitterUserInfoProvider;
public UserInfo createFromJsonString(String jsonspec) {
if(getUserType(jsonSpec) == TWITTER) {
TwitterUserInfo tui = twitterUserInfoProvider.get();
tui.initFromJson(jsonSpec);
return tui;
} else { /* ... */ }
}
}
...,當然,這如果您只需要界面並且想要在將來某個時間更改具體的課程,則還允許您注入@Twitter Provider<UserInfo>
。如果你想TwitterUserInfo
接受構造函數的參數,Assisted injection將幫助您創建一個TwitterUserInfoFactory
,雖然,這將有助於它向immutability:
public class UserInfoFactory {
@Inject TwitterUserInfo.Factory twitterUserInfoFactory;
public UserInfo createFromJsonString(String jsonspec) {
if(getUserType(jsonSpec) == TWITTER) {
return twitterUserInfoFactory.create(jsonSpec);
} else { /* ... */ }
}
}
// binder.install(new FactoryModuleBuilder().build(TwitterUserInfoFactory.class));
public class TwitterUserInfo implements UserInfo {
public interface Factory {
TwitterUserInfo create(String jsonSpec);
}
public TwitterUserInfo(@Assisted String jsonSpec, OtherDependency dep) { /* ... */ }
}
最後請注意:TwitterUserInfo
可能沒有任何dependencies--這聽起來像是一個數據對象 - 所以讓你的班級完全如何發現它(與new
)可能是最好的方法。儘管分離的接口和類可以減輕測試的負擔,但維護和理解成本很高。吉斯是一個非常強大的錘子,但並不是所有的東西都是釘子。
輔助注入在這裏的研究是一件好事,但不夠聰明,以基於JSON類結果返回不同的具體類型。如此處所述,Guice將無法爲UserInfoFactory提供實現,因爲它無法實例化接口UserInfo,並且未調用FactoryModuleBuilder.implement接口就是FactoryModuleBuilder可能返回的所有接口。 –
@JeffBowman - 如果你在Module.configure中有binder.install(新的FactoryModuleBuilder()。build(UserInfoFactory.class));在模塊public Class <?中添加一個函數擴展UserInfo> bindUserInfo(){返回GoogleUserInfo.class; }不起作用? (原諒我,我試圖從不同的角度來理解Guice,我有一個現有的應用程序,我使用的是Guice,我知道的是來自分析現有代碼庫。) –
FactoryModuleBuilder通過檢查傳入'build'的接口(不是具體的類!),併爲其提供可注入的實現。當你調用實現的方法時,FactoryModuleBuilder接受方法的返回類型並實例化它,用方法參數和Injector中的所有其他參數填充'@ Assisted'參數。如果返回類型是_interface_,就像'UserInfo'一樣,你還需要調用'implement'來告訴它要創建哪個具體類型。這就是爲什麼它不能在這裏工作 - 具體類型在配置時固定。 –