首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >将两个javascript对象连接在一起的正确方式是什么?

将两个javascript对象连接在一起的正确方式是什么?
EN

Stack Overflow用户
提问于 2009-03-06 17:29:26
回答 6查看 4.4K关注 0票数 16

我现在面临一个难题:怎样才是将两个javascript对象连接在一起的正确方法?

想象一个像文本编辑器这样的应用程序,它有几个不同的文件。我有一些表示notebook视图的HTML页面。我有一个包含NotebookController和Notebook View类定义的notebook.js文件。

负责在笔记本上执行业务逻辑的NotebookControler对象,如“保存笔记本”、“加载笔记本”、“新建笔记本”。NotebookView负责管理用于表示的超文本标记语言。它做一些低级的事情,比如"get/set notebook body“"get/set notebook name”。它还侦听DOM事件(onClick)和触发业务事件(saveNotebook)。这是我对被动视图模式的尝试。

我希望我的javascript客户端代码是面向对象的、分离的关注点和单元可测试的。我想用模拟NotebookView测试NotebookController,反之亦然。这意味着我不能只在NotebookController中实例化一个NotebookView。我也一样

  • 在我的notebook.js中加入了一些将两者连接在一起的逻辑
  • 在我的应用程序中有一个全局函数,它知道实例化其中一个并将它们连接在一起
  • 使用依赖注入,要么是自行开发的,要么是类似SquirrelIoc

在Java中,选择是很自然的:使用Spring。但这看起来不太像JavaScript-y。正确的做法是什么?

EN

回答 6

Stack Overflow用户

发布于 2009-03-06 20:03:46

依赖注入可能是你最好的选择。与Java语言相比,在JS代码中更容易做到这一点,因为您可以将一个充满回调的对象传递到NotebookController中。其他方面比较困难,因为您没有静态代码分析来形式化它们之间的接口。

票数 3
EN

Stack Overflow用户

发布于 2009-03-06 23:35:37

谢谢你的见解。我最终编写了一个简单的JavaScript依赖注入实用程序。经过一段时间的辩论和你的评论,我发现DI确实是正确的答案,因为:

  1. 它将连接的关注点从业务逻辑中完全分离出来,同时将连接逻辑保持在与被连接的事物相近的位置。
  2. 它允许我在我的对象上提供一个通用的“you all wire up”回调,这样我就可以完成3个阶段的初始化:实例化所有内容,连接所有内容,调用每个人的回调,并告诉他们它们已经连接。
  3. 很容易检查依赖项缺失问题。

下面是DI实用程序:

代码语言:javascript
复制
var Dependency = function(_name, _instance, _dependencyMap) {
    this.name = _name;
    this.instance = _instance;
    this.dependencyMap = _dependencyMap;
}

Dependency.prototype.toString = function() {
    return this.name;
}

CONCORD.dependencyinjection = {};

CONCORD.dependencyinjection.Context = function() {
    this.registry = {};
}

CONCORD.dependencyinjection.Context.prototype = {
    register : function(name, instance, dependencyMap) {
        this.registry[name] = new Dependency(name, instance, dependencyMap);
    }, 
    get : function(name) {
        var dependency = this.registry[name];
        return dependency != null ? dependency.instance : null;
    },

    init : function() {
        YAHOO.log("Initializing Dependency Injection","info","CONCORD.dependencyinjection.Context");
        var registryKey;
        var dependencyKey;
        var dependency;
        var afterDependenciesSet = [];
        for (registryKey in this.registry) {
            dependency = this.registry[registryKey];
            YAHOO.log("Initializing " + dependency.name,"debug","CONCORD.dependencyinjection.Context");

            for(dependencyKey in dependency.dependencyMap) {
                var name = dependency.dependencyMap[dependencyKey];
                var instance = this.get(name);
                if(instance == null) {
                    throw "Unsatisfied Dependency: "+dependency+"."+dependencyKey+" could not find instance for "+name;
                }
                dependency.instance[dependencyKey] = instance; 
            }

            if(typeof dependency.instance['afterDependenciesSet'] != 'undefined') {
                afterDependenciesSet.push(dependency);
            }
        }

        var i;
        for(i = 0; i < afterDependenciesSet.length; i++) {
            afterDependenciesSet[i].instance.afterDependenciesSet();
        }
    }

}
票数 3
EN

Stack Overflow用户

发布于 2009-03-06 19:54:30

我会说,把它们连在一起就行了:

代码语言:javascript
复制
function wireTogether() {
  var v = new View();
  var c = new Controller();
  c.setView(v);
}

当然,接下来会出现另一个问题--如何测试wireTogether()函数?

幸运的是,JavaScript是一种真正的动态语言,因此您只需为视图和控制器分配新的值:

代码语言:javascript
复制
var ok = false;

View.prototype.isOurMock = true;
Controller.prototype.setView = function(v) {
  ok = v.isOurMock;
}

wireTogether();

alert( ok ? "Test passed" : "Test failed" );
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/619701

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档