Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
var handlers = {};
function subscribe(evt, handler) {
if (!handlers[evt]) handlers[evt] = [];
handlers[evt].push(handler);
}
function trigger(evt, data) {
if (handlers[evt]) {
handlers[evt].forEach(function(handler) { handler(data); });
}
}
function Balance() {
this.balance = 0;
subscribe('UI.coinClicked', this.addCoins.bind(this));
}
Balance.prototype.addCoins = function() {
this.balance += 15;
trigger('Balance.changed', this.balance);
};
function WinWatcher() {
subscribe('Balance.changed', this.checkWin.bind(this));
}
WinWatcher.prototype.checkWin = function(balance) {
if (balance > 20) {
trigger('WinWatcher.userWins');
}
};
function UI() {
$('.coin').click(function() {
trigger('UI.coinClicked');
});
subscribe('WinWatcher.userWins', this.showWin.bind(this));
}
UI.prototype.showWin = function() {
$('.you_win').animate({opacity: 0});
};
subscribe('DOM.init', function () {
var ui = new UI(),
balance = new Balance(),
winWatcher = new WinWatcher();
});
function GatherStat() {
subscribe('UI.coinClicked', this.sendClick.bind(this));
subscribe('WinWatcher.userWins', this.sendWin.bind(this));
}
GatherStat.prototype.sendClick = function() {
$.post('/stat/gather/ajax', {click: 1, date: new Date});
};
GatherStat.prototype.sendWin = function() {
$.post('/stat/gather/ajax', {win: 1, date: new Date});
};
function UI() {
$('.coin').click(function() {
trigger('UI.coinClicked');
});
}
function UIWin() {
subscribe('WinWatcher.userWins', this.showWin.bind(this));
}
UI.prototype.showWin = function() {
$('.you_win').animate({opacity: 0});
};
— посмотрите на ваши конструкторы. при усложнении задачи они станут монструозными и в одном месте будет слишком много знаний о разных задачах. это плохо
— рефакторинг в моей версии сводится к копи-пасте методов, в вашей — ещё и к переорганизации конструкторов. Это дополнительные минуты. зачем эта лишняя трата времени?
— в вашем случае код, относящийся к задаче (подписка на событие и обработка этого события), лежит в двух разных местах, что опять ведёт к трате времени при изучении кода. Зачем? Одна задача — один метод, зачем усложнять?
— в вашем случае события — это просто строки. об автодополнении средствами IDE можно забыть. в моём автодополнение есть.
— в вашем случае нужно сперва догадаться, что в задаче будет правильнее использовать события. в моём случае фреймворк и сама технология подталкивает к правильному решению.
— ваши конструкции вроде «this.showWin.bind» — это ещё одна зависимость от какого-то фреймворка. зачем? в моём случае решение полно и не требует внешних зависимостей, предоставляя полный и удобный стек.
Не понял, почему при усложнении задачи мое решение должно стать монструознее вашей реализации?
function AnyConstr(){
this.prop1 = 0;
this.prop2 = '';
......
subscribe('event1', this.method1.bind(this));
subscribe('event2', this.method2.bind(this));
subscribe('event3', this.method3.bind(this));
subscribe('event4', this.method4.bind(this));
subscribe('event4', this.method5.bind(this));
subscribe('event4', this.method6.bind(this));
.......
}
Из реорганизации — перенос подписки на событие. В вашем случае, например, при выносе handleCoinClick надо будет перенести и EventPoint, а в моем случае только cut&paste метода, так что паритет, 1:1
надо будет перенести и EventPoint
В моем случае можно повесить один обработчик на несколько событий, и несколько обработчиков на одно
Core.CatchEvent(Event1, Event2, Event3, ...)
Так что в моем решении на одну зависимость меньше, что явно лучше, 3:2
Вот так будут выглядеть ваши конструкторы при мало-мальском усложнении задачи.
var AnyConstr = {};
AnyConstr.Event1 = function () {
Core.CatchEvent(Some.Event1);
// ...
};
AnyConstr.Event2 = function () {
Core.CatchEvent(Some.Event2);
// ...
};
AnyConstr.Event3 = function () {
Core.CatchEvent(Some.Event3);
// ...
};
AnyConstr.Event4 = function () {
Core.CatchEvent(Some.Event4);
// ...
};
AnyConstr.Event5 = function () {
Core.CatchEvent(Some.Event5);
// ...
};
AnyConstr.Event6 = function () {
Core.CatchEvent(Some.Event6);
// ...
};
угу, тот же copy-paste, что займёт не более пяти секунд у программиста в здравом уме и с незагипсованной рукой ))
Несколько обработчиков на одно событие, описанных в одном месте — вот это как раз и противоречит концепции event-driven.
функции trigger и subscribe — это тоже зависимости,
Технология CORE