Я в настоящее время сталкиваюсь с загадкой: Что правильный путь состоит в том, чтобы соединить проводом вместе 2 объекта JavaScript?
Вообразите приложение как текстовый редактор с несколькими различными файлами. У меня есть некоторая страница HTML, которая представляет представление для ноутбука. У меня есть файл notebook.js, который содержит определения классов для Представления NotebookController и Ноутбука.
Объект NotebookControler, ответственный за выполнение бизнес-логики на Ноутбуке как ", Сохраняет Ноутбук", "Ноутбук Загрузки", "Новый Ноутбук". NotebookView ответственен за управление HTML, который используется для презентации. Это делает низкоуровневый материал как, "получают/устанавливают, корпус ноутбука" "получают/устанавливают название ноутбука". Это также прислушивается к событиям DOM (onClick) и запускает бизнес-события (saveNotebook). Это - моя попытка Пассивного шаблона Представления.
Я хочу, чтобы мой JavaScript клиентский код был объектно-ориентированными, разделенными проблемами, и тестируемый единицей. Я хочу протестировать NotebookController с ложным NotebookView и наоборот. Это означает, что я не могу только инстанцировать NotebookView в NotebookController.Я тоже
В Java выбором является естественный: используйте Spring. Но это не кажется очень JavaScript-y. Каков правильный поступок?
Внедрение зависимости является, вероятно, Вашим лучшим выбором. По сравнению с Java некоторые аспекты этого легче сделать в коде JS, так как можно передать объект, полный обратных вызовов в NotebookController. Другие аспекты более трудны, потому что у Вас нет статического анализа кода для формализации интерфейса между ними.
Спасибо за понимание. Я закончил тем, что писал простую утилиту внедрения зависимости 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();
}
}
}
Я сказал бы, просто соединил бы их проводом вместе:
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" );
Я попытаюсь попробовать это, но это будет немного трудно, не видя фактического кода. Лично, я никогда не видел, что кто-либо делает такую определенную попытку (M) VC с JavaScript или МОК в этом отношении.
, В первую очередь, с чем Вы собираетесь протестировать? Если Вы уже не имеете, проверяете Тестовое видео YUI , который имеет некоторую хорошую информацию о поблочном тестировании с JavaScript.
, Во-вторых, когда Вы говорите "лучший способ обеспечить электричеством то агрегирование", я, вероятно, просто сделал бы это как метод set w/the контроллер
// Production
var cont = new NotebookController();
cont.setView( new NotebookView() );
// Testing the View
var cont = new NotebookController();
cont.setView( new MockNotebookView() );
// Testing the Controller
var cont = new MockNotebookController();
cont.setView( new NotebookView() );
// Testing both
var cont = new MockNotebookController();
cont.setView( new MockNotebookView() );
, Но это делает некоторое большое предположение о том, как Вы разработали свой контроллер и уже просматриваете объекты.