这是一个小型的爱好项目,我知道虽然这里使用的一些东西,如包装纸甚至DI都不是必需的,但它们是用于学习目的。
以前在阅读Spring
的文档时,我已经阅读了很多次,非常强调没有代码必须依赖于DI框架。这是有道理的:你编写了具有某些依赖关系的库类,他们知道他们会以某种方式接收它们,但并不真正关心它们。这样就可以在没有DI的情况下在其他地方使用和共享这些库类,没有或只有很少的更改。
Google Guice用作DI框架(它的重量轻!)。
此时,有一个类具有使用@Inject
注释声明的依赖项。在Factory
内构建此类时,无法直接调用DI
有一个接口,它是套接字对象的包装器:
interface ClientContainer {
interface ClientContainerFactory {
ClientContainer getFrom(Socket s);
}
public Socket getSocket();
// .... Other stuff applicable to a client. Removed for brevity.
}
工厂,隐藏ClientContainer
的具体实施:
// Package local concrete class.
class SampleContainerImpl implements ClientContainer {
// Observers are notified on various events such as
// Client closed the connection and...
private final List<Observer> observers = new List<>();
// A default observer implementation must be provided in
// order to cleanup and close resources when exceptions
// occur. It means if a IOException is raised while reading
// from client socket, SampleContainerImpl will not close
// that socket but delegates the task to this class.
private Observer defaultObserverInCaseOfException;
// Such a long name!
@Inject
void inCaseOfExceptionObserverSetter(Observer<ClientContainer> o) {
this.defaultObserverInCaseOfException = o;
}
SampleContainerImpl(Socket clientSocket) {
this.socket = clientSocket;
}
// Rest of the code removed for brevity
}
为了隐藏我的具体类,我在具体类的同一个包中创建了一个工厂,但是使用了公共访问修饰符。问题就在这里:
public class SampleFactory implements ClientContainer.ClientContainerFactory {
public ClientContainer getFrom(final Socket s) {
final ClientContainer c = new ClientContainer(s);
// Okay... what to do with our class who has an @Inject?
// The only way I can think of is to make SampleFactory
// aware of the DI -> bad. DI is not a service locator,
// and I do not want to use a service locator either!
return c;
}
}
答案 0 :(得分:0)
这很有趣,我现在可以看到问题:
在考虑DI时,实施ClientContainer.ClientContainerFactory
是没用的,也是个坏主意。 ClientContainer
必须从DI获得。对于直到主根的其他类也是如此。
这是对的吗?