我有一个Utility / constants类,其中包含一个Map<String, Authorizer>
,其中Authorizer
是具有一些不同实现的接口。我使用跨不同流的地图来获取一个对象,该对象包含一些String
(授权方法的名称),然后该对象映射到特定的Authorizer
,然后完成一些授权。
我正在使用Guice连接Authorizer
类,但是这种方法使我无法使实用程序类(包含Map
)成为具有空私有构造函数的真正的实用程序类。我有一个时髦的解决方法,可以让Guice和Checkstyle都满意,但是我想知道是否有更好的方法。
我的实用程序类:
public final class Constants {
@Inject
private Constants() {}
public static final String AUTH_METHOD_ONE = "Auth1";
public static final String AUTH_METHOD_TWO = "Auth2";
@Singleton
@Inject
@Getter // For Checkstyle, as AUTH_METHODS isn't a true static final constant
private static Map<String, Authorizer> authMethods;
}
我的常数模块:
public class ConstantsModule extends AbstractModule {
@Override
public void configure() {
requestStaticInjection(Constants.class);
final MapBinder<String, Authorizer> mapBinder = MapBinder.newMapBinder(binder(), String.class, Authenticator.class);
mapBinder.addBinding(AUTH_METHOD_ONE).to(MethodOneAuthorizer.class);
mapBinder.addBinding(AUTH_METHOD_TWO).to(MethodTwoAuthorizer.class);
}
}
以及用法示例:
public class AuthorizationOrchestrator {
private static Authorizer getAuthorizer(final AuthorizationState state) {
return state.getMethods().stream()
.map(AuthorizationApproach::getAuthorizationApproachName)
.filter(Constants.getAuthMethods().keySet()::contains)
.findFirst()
.map(Constants.getAuthMethods()::get)
.orElse(null);
}
}
此方法还需要在单元测试中使用一些PowerMock。有没有更好的方法:
Authorizer
类,同时将映射保留在一个地方?Constants
类与public static final Map<String, Authorizer> AUTH_METHODS
一起用作真正的实用程序类,同时仍然可以将授权者注入Map
中吗?答案 0 :(得分:1)
注入应该是常量的东西真的没有意义。
通过使用静态Constants
类,您正在将非注入式依赖项引入使用Constants
类的代码中,这与DI的观点背道而驰-更不用说静态依赖项了在测试中更难模拟。
还有其他几种方法可能对您有用。原则上,它们都是相同的解决方案(将Authorizer
注入到非静态对象中),但是它们有一些细微差别。
使用合成避免使用实用程序类。制作由多个Authorizer
组成的Authorizer
实现。复合Authorizer
可以在内部委派给正确的“真实”实现。然后,您只需在需要的任何位置注入一个Authorizer
。取决于Authorizer
合同的定义方式,可能无法启用。
在实用程序类中保留任何状态的逻辑。将静态方法的签名更改为getAuthorizer(AuthorizationState state, Map<String, Authorizer> availableAuthorizersByName)
。然后,将AUTH_METHODS
映射直接注入到将要调用静态getAuthorizer
方法的类中,并将该映射作为方法的参数之一传递。
使getAuthorizer()
不是静态的。,然后将地图直接注入AuthorizationOrchestrator
的实例中。