什么是正确的方法连接在一起2个JavaScript对象? [英] What is the right way to wire together 2 javascript objects?

查看:121
本文介绍了什么是正确的方法连接在一起2个JavaScript对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正面临一个难题:将两个JavaScript对象连接在一起的正确方法是什么?



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



NotebookControler对象负责在笔记本上执行业务逻辑,如保存笔记本,加载笔记本,新笔记本。 NotebookView负责管理用于演示的HTML。它是低级的东西,如获取/设置笔记本体获取/设置笔记本名称。它还监听DOM事件(onClick)并触发业务事件(saveNotebook)。这是我对被动视图模式的尝试。



我希望我的JavaScript客户端代码面向对象,分开的关注点和单元测试。我想用一个模拟NotebookView测试NotebookController,反之亦然。这意味着我不能在NotebookController中实例化NotebookView。我的笔记本电脑中的一些逻辑可以把它们连接在一起
$ b

  • 我的应用程序中的一个全局功能,可以实例化其中一个并将它们连接在一起

  • 使用依赖注入,一个本地生长的或者像SquirrelIoc



  • 在Java中,选择是自然的:使用Spring。但这似乎不是JavaScript-y。什么是正确的事情?

    解决方案

    感谢您的洞察力。我最终写了一个简单的JavaScript依赖注入实用程序。经过一段时间的辩论和你的意见,发生在我身上,DI真的是正确的答案,因为:


    1. 完全分离了连线业务逻辑,同时保持布线逻辑接近有线连接。

    2. 它允许我通常在我的对象上提供一个你们都连线的回调,这样我就可以可以做一个3阶段的初始化:实例化一切,将其全部连接起来,调用所有人的回调,并告诉他们他们有线。

    3. 很容易检查依赖缺失的问题。 >

    所以这里是DI实用程序:

      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 = {
    注册:function(name,instance,dependencyMap){
    this.registry [name] = new Dependency (name,instance,dependencyMap);
    },
    get:function(name){
    var dependency = this.registry [name];
    返回依赖关系!= null? dependency.instance:null;
    },

    init:function(){
    YAHOO.log(初始化依赖注入,info,CONCORD.dependencyinjection.Context);
    var registryKey;
    var dependencyKey;
    var依赖;
    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不满足依赖关系:+ dependency +。+ dependencyKey +找不到+ 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();
    }
    }

    }


    I'm currently facing a conundrum: What is the right way to wire together 2 javascript objects?

    Imagine an application like a text editor with several different files. I have some HTML page that represents the view for the notebook. I have a file notebook.js that contains class definitions for NotebookController and Notebook View.

    NotebookControler object responsible for performing business logic on the Notebook like "Save Notebook," "Load Notebook," "New Notebook." NotebookView is responsible for managing the HTML that is used for presentation. It does low level stuff like "get/set notebook body" "get/set notebook name." It also listens for DOM events (onClick) and fires business events (saveNotebook). This is my attempt at the Passive View pattern.

    I want my javascript client-side code to be object-oriented, separated concerns, and unit-testable. I want to test NotebookController with a mock NotebookView and vice versa. This means that I can't just instantiate a NotebookView inside the NotebookController. So do I

    • Put some logic in my notebook.js that wires the 2 together
    • Have a global function in my application that knows to instantiate one of each and wire them together
    • Use Dependency Injection, either a home-grown one or something like SquirrelIoc

    In Java, the choice is a natural one: use Spring. But that doesn't seem very JavaScript-y. What's the right thing to do?

    解决方案

    Thanks for the insight. I ended up writing a simple JavaScript dependency injection utility. After debating for a while and your comments, it occured to me that DI was really the right answer because:

    1. It totally separated the concerns of wiring from the business logic while keeping the wiring logic close to the things being wired.
    2. It allowed me to generically provide a "you're all wired up" callback on my objects so that I could do a 3 phase initialization: instantiate everything, wire it all up, call everyone's callbacks and tell them they're wired.
    3. It was easy to check for dependency missing problems.

    So here's the DI utility:

    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();
            }
        }
    
    }
    

    这篇关于什么是正确的方法连接在一起2个JavaScript对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆