Что правильный путь состоит в том, чтобы соединить проводом вместе 2 объекта JavaScript?

Я в настоящее время сталкиваюсь с загадкой: Что правильный путь состоит в том, чтобы соединить проводом вместе 2 объекта JavaScript?

Вообразите приложение как текстовый редактор с несколькими различными файлами. У меня есть некоторая страница HTML, которая представляет представление для ноутбука. У меня есть файл notebook.js, который содержит определения классов для Представления NotebookController и Ноутбука.

Объект NotebookControler, ответственный за выполнение бизнес-логики на Ноутбуке как ", Сохраняет Ноутбук", "Ноутбук Загрузки", "Новый Ноутбук". NotebookView ответственен за управление HTML, который используется для презентации. Это делает низкоуровневый материал как, "получают/устанавливают, корпус ноутбука" "получают/устанавливают название ноутбука". Это также прислушивается к событиям DOM (onClick) и запускает бизнес-события (saveNotebook). Это - моя попытка Пассивного шаблона Представления.

Я хочу, чтобы мой JavaScript клиентский код был объектно-ориентированными, разделенными проблемами, и тестируемый единицей. Я хочу протестировать NotebookController с ложным NotebookView и наоборот. Это означает, что я не могу только инстанцировать NotebookView в NotebookController.Я тоже

  • Поместите некоторую логику в мой notebook.js, который соединяет 2 проводом вместе
  • Имейте глобальную функцию в моем приложении, которое знает, чтобы инстанцировать одного из каждого и соединить их проводом вместе
  • Используйте Внедрение зависимости, или собственной разработки или что-то как SquirrelIoc

В Java выбором является естественный: используйте Spring. Но это не кажется очень JavaScript-y. Каков правильный поступок?

16
задан Robert Harvey 13 April 2012 в 17:14
поделиться

4 ответа

Внедрение зависимости является, вероятно, Вашим лучшим выбором. По сравнению с Java некоторые аспекты этого легче сделать в коде JS, так как можно передать объект, полный обратных вызовов в NotebookController. Другие аспекты более трудны, потому что у Вас нет статического анализа кода для формализации интерфейса между ними.

3
ответ дан 30 November 2019 в 23:14
поделиться

Спасибо за понимание. Я закончил тем, что писал простую утилиту внедрения зависимости 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 = {
    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
ответ дан 30 November 2019 в 23:14
поделиться

Я сказал бы, просто соединил бы их проводом вместе:

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" );
2
ответ дан 30 November 2019 в 23:14
поделиться

Я попытаюсь попробовать это, но это будет немного трудно, не видя фактического кода. Лично, я никогда не видел, что кто-либо делает такую определенную попытку (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() );

, Но это делает некоторое большое предположение о том, как Вы разработали свой контроллер и уже просматриваете объекты.

0
ответ дан 30 November 2019 в 23:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: