我现在面临一个难题:怎样才是将两个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。我也一样
的
在Java中,选择是很自然的:使用Spring。但这看起来不太像JavaScript-y。正确的做法是什么?
发布于 2009-03-06 20:03:46
依赖注入可能是你最好的选择。与Java语言相比,在JS代码中更容易做到这一点,因为您可以将一个充满回调的对象传递到NotebookController中。其他方面比较困难,因为您没有静态代码分析来形式化它们之间的接口。
发布于 2009-03-06 23:35:37
谢谢你的见解。我最终编写了一个简单的JavaScript依赖注入实用程序。经过一段时间的辩论和你的评论,我发现DI确实是正确的答案,因为:
下面是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 = {
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();
}
}
}
发布于 2009-03-06 19:54:30
我会说,把它们连在一起就行了:
function wireTogether() {
var v = new View();
var c = new Controller();
c.setView(v);
}
当然,接下来会出现另一个问题--如何测试wireTogether()函数?
幸运的是,JavaScript是一种真正的动态语言,因此您只需为视图和控制器分配新的值:
var ok = false;
View.prototype.isOurMock = true;
Controller.prototype.setView = function(v) {
ok = v.isOurMock;
}
wireTogether();
alert( ok ? "Test passed" : "Test failed" );
https://stackoverflow.com/questions/619701
复制相似问题