其他分享
首页 > 其他分享> > 【译】依赖注入

【译】依赖注入

作者:互联网

引子

在尝试运用 Scalable Frontend 1 — Architecture Fundamentals 里面所说的 Dependency Injection(依赖注入)时,感觉有些不清不楚,找了些资料,才更明白了一些,在此翻译记录部分聚合。

依赖注入是什么

在软件工程中,依赖注入是一种一个对象接收它所依赖的其它对象的技术。这些其它对象称为依赖。在典型的“使用”关系中,接收对象称为客户端(client),传递的(即“注入的”)对象称为服务(service)。将服务传递给客户端的代码可以是多种类型的东西,称为注入器。注入器告诉客户端要使用什么服务,而不是客户端指定要使用哪个服务。“注入”是指将依赖项(服务)传递到将使用它的对象(客户端)中。

服务是客户端状态的一部分。将服务传递给客户端,而不是让客户端构建或查找服务,是该模式的基本要求。

优势

劣势

依赖注入的几种形式

客户端对象至少有三种方式可以接收对外部模块的引用:构造器注入、设置器注入、接口注入。

构造器注入

依赖项是通过客户端的类构器提供的参数传入。

// Constructor
Client(Service service) {
    // Save the reference to the passed-in service inside this client
    this.service = service;
}

当可以首先构造所有依赖项时,最好使用它,因为它可以用来确保客户端对象始终处于有效状态,而不是使其某些依赖项引用为 null(不设置)。但就其本身而言,它缺乏在以后更改其依赖项的灵活性。这可能是使客户端不可变从而实现线程安全的第一步。

// Constructor
Client(Service service, Service otherService) {
    if (service == null) {
        throw new InvalidParameterException("service must not be null");
    }
    if (otherService == null) {
        throw new InvalidParameterException("otherService must not be null");
    }

    // Save the service references inside this client
    this.service = service;
    this.otherService = otherService;
}

设置器注入

这种方式需要客户端提供一个设置器给依赖性。

// Setter method
public void setService(Service service) {
    // Save the reference to the passed-in service inside this client.
    this.service = service;
}

要求客户端为每个依赖项提供设置器。这样就可以随时自由地操作依赖项引用的状态。这提供了灵活性,但是如果要注入多个依赖项,那么客户端很难确保在能够使用之前已注入所有依赖项。

因为这些注入是独立发生的,所以无法判断注入器何时完成了与客户机的连接。依赖项可能仅仅因为调用其设置器失败而保留为 null 。这将强制检查从客户端组装时到使用时的注入是否已完成。

// Set the service to be used by this client
public void setService(Service service) {
    this.service = service;
}

// Set the other service to be used by this client
public void setOtherService(Service otherService) {
    this.otherService = otherService;
}

// Check the service references of this client
private void validateState() {
    if (service == null) {
        throw new IllegalStateException("service must not be null");
    }
    if (otherService == null) {
        throw new IllegalStateException("otherService must not be null");
    }
}

// Method that uses the service references
public void doSomething() {
    validateState();
    service.doYourThing();
    otherService.doYourThing();
}

接口注入

这只是客户端将角色接口发布到客户端依赖项的设置方法。它可以用来确定在注入依赖项时注入器应该如何与客户端对话。

// Service setter interface.
public interface ServiceSetter {
    public void setService(Service service);
}

// Client class
public class Client implements ServiceSetter {
    // Internal reference to the service used by this client.
    private Service service;

    // Set the service that this client is to use.
    @Override
    public void setService(Service service) {
        this.service = service;
    }
}

接口注入的优点是依赖项可以完全忽略它们的客户端,但是仍然可以接收对新客户端的引用,并使用它,将自身的引用发送回客户端。这样,依赖项就变成了注入器。关键是注入方法(可能只是一个经典的设置器方法)是通过一个接口提供的。

参考资料

标签:依赖,service,Service,注入,客户端,otherService
来源: https://blog.csdn.net/u011194386/article/details/117652719