Объектно-ориентированный JS - без глобальных переменных? - PullRequest
2 голосов
/ 01 октября 2011

Я использую объектно-ориентированный подход к созданию приложения Javascript. Для начала я создаю объект Game и объект Timer.

Вот моя текущая реализация: Объект Timer имеет следующие методы:

setTimerValue()  
start()  
stop()  
getTimeLeft()  
timeExpired()

Объект Game имеет следующие методы:

reset()
run()
...

Timer.start() использует window.setInterval(), чтобы начать обратный отсчет. Когда обратный отсчет достигает нуля, он вызывает Timer.timeExpired().

Timer.timeExpired() объявляет, что игра окончена и должна вызвать Game.reset() и Game.run(), чтобы перезапустить игру. Но как это сделать, если объект Timer ничего не знает об объекте Game?

Должен ли объект Game быть глобальной переменной, чтобы это работало?

Кроме того, объект Game в настоящее время имеет объект Timer в качестве одного из своих свойств. Это позволяет объекту Game вызывать методы Timer. Но неясно, как методы Timer могут вызывать объект Game.

У меня есть подозрение, что я создаю слишком много зависимостей между объектами и могу использовать некоторые предложения о том, как лучше это спроектировать.

Спасибо всем.

1 Ответ

4 голосов
/ 01 октября 2011

Используйте управляемый событиями подход или шаблон проектирования наблюдателя.Javascript имеет одну из гибких событийно-ориентированных реализаций из моего опыта.Таким образом, у вас есть объект Timer, который на самом деле не должен знать ни о каких других объектах.Когда вы вызываете Timer.start (), объект должен генерировать пользовательское событие, например «timerStarted», аналогично для других методов:

Timer.stop() - > emits "timerStoped"
Timer.timeExpired() -> emits "timerExpired"

Для каждого события, вызванного Timer, должно быть событиеобработчик, который будет вызываться при запуске события coresponding.

Если вы используете jquery, обработка событий должна быть тривиальной:

var $ = jQuery.noConflict();
var timer = new Timer();
var game  = new Game();

$(timer).bind('timerStarted', function(e) {
    game.doSomething();
});

в Timer :: start (), который вы должны написать:

start: function() {
    $(this).trigger('timerStarted');
}

Другой подход заключается в использовании обратных вызовов: если вы хотите, чтобы что-то было сделано при запуске таймера, вы можете передать лямбда-функцию методу запуска таймера:

// timer method
start: function(callback) {
    if(typeof(callback) == 'function') {
        callback();
    }
}

// main logic
var timer = new Timer();
var game  = new Game();

timer.start(function() {
    game.doSomething();
});

Надеюсь, вы получите идею

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...