假设我的代码有以下 3 层:
1.数据库层(ORM)
2.业务逻辑
3.申请
现在,我编写代码如下:
数据库层:
这主要是对数据库进行CURD操作。class MyDatabaseLayer { public int findValue(int k) { // find v } public void insertValue(int k, int v) { // Insert v } }
业务逻辑:
这包含调用数据库层并执行操作的实际逻辑。class MyBusinessLogic { private MyDatabaseLayer dbLayer; public MyBusinessLogic(MyDatabaseLayer dbLayer) { this.dbLayer = dbLayer; } public int manipulateValue(int k) { dbLayer.findValue(k); //do stuff with value } }
应用层:
这将调用业务逻辑并显示数据MyBusinessLogic logic = new MyBusinessLogic(new MyDatabaseLayer ()); //The problem logic.manipulateValue(5);
现在,如果您在应用程序层中看到,它就知道数据库层,这是错误的。它知道的太多了。
米斯科·赫弗里 says :构造函数注入(inject)很好。但如果我遵循这一点,我将如何实现抽象? Google Guice 可以如何帮助我?
最佳答案
请注意,对于 Misko 所指的可测试性,您理想情况下希望为 MyDatabaseLayer
制作接口(interface) , MyBusinessLogic
等,并让构造函数采用这些接口(interface)而不是具体的类,以便在测试中您可以轻松地传入实际上不使用数据库等的虚假实现。
使用 Guice,您可以将接口(interface)绑定(bind)到 Module
中的具体类。或Module
s。然后您将创建一个 Injector
使用那些Module
s 并从 Injector
获取一些根对象(例如,您的应用程序对象) .
Injector injector = Guice.createInjector(new AbstractModule() {
@Override protected void configure() {
bind(MyDatabaseLayer.class).to(MyDatabaseLayerImplementation.class);
// etc.
});
MyApplicationLayer applicationLayer = injector.getInstance(MyApplicationLayer.class);
在 MyApplicationLayer
,您将注入(inject)业务逻辑:
@Inject
public MyApplicationLayer(MyBusinessLogic logic) {
this.logic = logic;
}
这当然是一个非常简单的示例,您可以做更多复杂的事情。例如,在 Web 应用程序中,您可以使用 Guice Servlet 在 servlet 上使用构造函数注入(inject),而不是直接从 Injector
中获取对象。创建后。
关于java - 使用构造函数注入(inject)正确设计为可测试性而构建的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8176463/