java - 使用构造函数注入(inject)正确设计为可测试性而构建的类

标签 java inversion-of-control class-design guice testability

假设我的代码有以下 3 层:
1.数据库层(ORM)
2.业务逻辑
3.申请

现在,我编写代码如下:

  1. 数据库层:
    这主要是对数据库进行CURD操作。

    class MyDatabaseLayer {
        public int findValue(int k) {
            // find v
        }
    
        public void insertValue(int k, int v) {
            // Insert v
        }
    }
    
  2. 业务逻辑:
    这包含调用数据库层并执行操作的实际逻辑。

    class MyBusinessLogic {
        private MyDatabaseLayer dbLayer;
        public MyBusinessLogic(MyDatabaseLayer dbLayer) {
            this.dbLayer  = dbLayer;
        }
    
        public int manipulateValue(int k) {
            dbLayer.findValue(k);
            //do stuff with value
        }
    }
    
  3. 应用层:
    这将调用业务逻辑并显示数据

    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/

相关文章:

java - Jenkins 无法连接到 ldaps ://server

java - Spring 验证和@Valid

java - 实现 Spring IOC 时如何避免使用 ApplicationContext.getBean()

.net - 温莎城堡内部构造函数/类

c++ - 在这种情况下如何保持良好的数据封装?

java - Object.toString() 如何获得 "memory address"以及如何模仿它

android 中的 java.lang.NoSuchMethodError :org. json.JSONArray 错误

通过 IoC 容器实例化 WCF 服务

c++ - 编译器向空类声明添加了什么?

C++:应用复合模式