可分发的Javascript库中的依赖注入?

时间:2013-06-09 16:54:00

标签: javascript backbone.js dependency-injection

我们正在使用Backbone来创建可重用的组件。我们创建控制器以设置模型和视图之间的绑定。我们希望为人们提供用自己的实现替换模型和视图的能力。

由于大多数人都会使用我们提供的组件,因此我不想强迫开发人员配置或创建任何与默认组件无异的内容。

这意味着某人应该能够将他们想要用作模型或视图的对象实例传递给控制器​​,所有配置和设置都准备就绪,或者他们可以将某些配置传递给控制器将默认使用。

我不确定最好的方法是什么。

// Idea #1
var controller = new Controller({
    dependencyA: {
         conf: { // config for depedencyA }
    },
    dependencyB: {
         conf: { // config for dependencyB }
         class: custom.implement.Class
    }
});

在这种方法中,用户无法控制如何实例化对象。例如,Backbone模型在构造函数中采用两个参数,而视图只采用一个参数。

// Idea #2
var controller = new Controller({
    dependencyA: {
        args: ['arg1',{
            opt1: 'opt-value',
        }]
    },
    dependencyB: {
        args: ['a','b','c']
        class: custom.implement.Class
    }
});

Args将是传递给构造函数的参数。这意味着控制器使用args数组调用构造函数,如果您为默认依赖项传递自定义配置,这只会对您有所帮助。如果你想通过自己的实现,那就更尴尬了。

// Idea #3  
var controller = new Controller({
    dependencyA: new outOfBoxModel({ // configuration }),
    dependencyB: new custom.imeplement.Class('a','b','c')
});

在这种方法中,用户被迫实例化开箱即用模型。如果模型的默认设置都是合适的,那么用户正在做不必要的工作。他们唯一需要做的就是创建自己的自定义实现的实例。

我不确定这里最好的方法是什么?

1 个答案:

答案 0 :(得分:2)

在这三种方法中,我最喜欢方法编号3.这就是为什么:

  1. 它比其他方法更加一致。在第三种方法中,用户只需学习将构造的依赖实例传递到控制器中。在其他方法中,用户必须传入args,args和类名。
  2. 它不违反Single Responsibility Principle 。在前两种方法中,您的控制器负责构建和配置其依赖项。这根本不像依赖注入!我认为将依赖关系构建留给用户或应用程序的其他部分会更好,更简单。在我看来,强制用户构造自己的实现并不是一件可怕的事情 - 它让他们可以自由地定义他们想要的构造函数,而不是强迫你为Controllers依赖项定义和维护构造函数API。 ,并强迫用户遵守它们。
  3. 一个不同的想法:

    如果您在应用程序中拥有这种自由,我会考虑将您的Controller构造逻辑放在工厂类或方法中:

    var createController = function(config) {
      // Parse, validate, extract relevant config items
      // var a = create dependency a
      // var b = create dependency b
      return new Controller(a, b);
    }
    

    这种方法可以让你根据自己的定义config变得像你想要的那样 - 你可以支持你在原帖中提供的所有三个配置定义 - 虽然我不建议:-) 。至少,我会让工厂方法支持零args调用(在这种情况下,它将返回Controller的默认构造)和您首选的配置定义之一。