我有一个看起来像这样的类,它根据从凭证服务检索的凭据充当客户端的工厂。它构建客户端一次,并在每次调用时返回。
public class ClientFactory {
private CredentialService credentialService;
private ClientA clientA;
public ClientFactory(CredentialService credentialService){
this.credentialService = credentialService;
//initialization in constructor
this.clientA = buildClientA(credentialService.getCredentials());
}
public ClientA getClientA(){
return clientA;
}
/** Build new ClientA using crendentials*/
private ClientA buildClientA(String credentials){
return new ClientA(credentials);
}
}
我看到的问题是构造函数中的第2行,它基本上开始使用依赖关系' credentialService'立即初始化其他依赖项。如果其他开发人员在构造函数中移动代码的顺序,它将开始失败。其他选项也是改变方法getClientA()
。
public ClientA getClientA(){
if(clientA == null) {
this.clientA = buildClientA(credentialService.getCredentials());
}
return clientA;
}
但它有线程安全问题。有没有更好的方法来设计上面的课程,这避免了我上面强调的问题?
由于
答案 0 :(得分:3)
好吧,
this.clientA = buildClientA(credentialService.getCredentials());
依赖于传递给构造函数的参数credentialService
,而不是成员this.credentialService
。因此,初始化的顺序并不重要。
答案 1 :(得分:1)
只是不要将对CredentialService
的引用保存为实例变量,并继续将credentialService.getCredentials()
传递给bulldClientA
。您尚未使用实例变量credentialService
。
答案 2 :(得分:1)
你所谓的ClientFactory
看起来只是ClientA
。那么,如果您想避免创建额外的ClientA
个对象,为什么不让工厂依赖凭据并共享对ClientA
的引用呢?
public class ClientFactory {
private final CredentialService credentialService;
public ClientFactory(CredentialService credentialService){
this.credentialService = credentialService;
}
public ClientA newClientA(String credentials){
return new ClientA(credentials);
}
}
如果您想拥有潜在客户群,则可以共享Supplier<ClientA>
。
Supplier<ClientA> simpleSupplier = Suppliers.ofInstance(ClientFactory.newClientA()); // guava
Supplier<ClientA> allNewSupplier = () -> ClientFactory.newClientA(); // java 8 lambda
ClientA cachedClient = simpleSupplier.get();
ClientA newClient = allNewSupplier.get();