Антон Веретенников и Илья Семаков. Презентация

Post on 11-Jul-2015

202 views 3 download

Transcript of Антон Веретенников и Илья Семаков. Презентация

Антон ВеретенниковИлья Семаков

«ПЕРЕХОД ОТ КОЛЛБЕКОВК СОБЫТИЯМ»

Public API

Frontend BackendAJAX

разработать frontend-часть для нового проекта заказчика

Задача:

Search

Results

Filter #1

1 2 ... N

Filter #2

разработать frontend-часть для нового проекта заказчика

Задача:

Frontend

Filter #3

Combobox

Sort

CheckboxCheckboxCheckbox

Checkbox

TitleLorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore

CheckboxCheckbox

Combobox

CheckboxCheckboxCheckbox

CheckboxCheckboxCheckbox

разработать frontend-часть для нового проекта заказчика

Задача:

Пути решения

Callback

разработать frontend-часть для нового проекта заказчика

Задача:

Event-driven

Пути решения

разработать frontend-часть для нового проекта заказчика

Задача:

Callback Event-driven

?

Пути решения

Component_1 = {  update : function( callback ) { callback() },  reset : function( callback ){ callback() }};

Component_2 = {  business : function(){   Component_1.update(this.callback);  },  callback : function(){ ... }};

Callback

Сначала все выглядит вот так

Component_1 = {  update : function( callback ) { callback() }, reset : function( callback ){ callback() }};

Component_2 = {  business : function(){   Component_1.update(this.callback);  },  callback : function(){ ... }};

Component_3 = {  business : function(){   Component_1.reset(this.callback);  },  callback : function(){ ... }};

Callback

Появляются новые требования

Component_1 = {  update : function( callback ) { callback() },  reset : function( callback ){ callback() }};

Component_2 = {  business : function(){    Component_1.update(this.callback);  },  callback : function(){ ... }};

Component_3 = {  business : function(){    Component_1.reset(this.callback);  },  callback : function(){ ... }};

Component_4 = {  business : function(){    Component_2.business();  }};

Callback

... и ещё

Callback

... а в итоге получаем

Callback

Хорошо работают на несложных проектах.—

— Слабая гибкость из-за постоянно возрастающих зависимостей.

Module_2

Component_3Manager

Event

Component_4

Module_1

Component_1

Component_2

Event-driven. Теория

Event-driven. Теория

Component_3 = {  construct : function(){    Manager.addListener('completeReset', this.callback);  },  business : function(){    Manager.fireEvent('needReset');  },  callback : function(){ ... }};

Component_4 = {  business : function(){    Manager.fireEvent('needBusiness');  }};

Manager = {  addListener : function(){ ... },  fireEvent : function(){ ... }};

Component_1 = {  construct : function(){    Manager.addListener('needUpdate', this.update);    Manager.addListener('needReset', this.reset);  },  update : function(){    Manager.fireEvent('completeUpdate');  },  reset : function(){    Manager.fireEvent('completeReset');  }};

Component_2 = {  construct : function(){    Manager.addListener('needBusiness', this.business);    Manager.addListener('completeUpdate', this.callback);  },  business : function(){    Manager.fireEvent('needUpdate');  },  callback : function(){ ... }};

С точки зрения кода Manager — тот же Module.

В нашем случае, часть функций менеджера выполняется jQuery.

Другая часть выполняется одним из компонентов.

Manager «размазало» по коду :)Но дискомофорта из-за этого не испытываем.

Module_2

Component_3Manager

Event

Component_4

Module_1

Component_1

Component_2

Event-driven. Практика

Вызов событий

Генерируем сразу на компоненте.Избавились от посредников.

Module_2

Component_3Manager

Event

Component_4

Module_1

Component_1

Component_2

Event-driven. Практика

Шина.

Непосредственно на компоненте.

Специально созданный объект (proxy).

RequestSender = function( elem ){    this.$element = jQuery(elem);    ...  }

  RequestSender.prototype._getData = function(){    this.$element.trigger('js-waiting-data');  }

Вызов событий

Генерируем сразу на компоненте.Избавились от посредни ков.

Module_2

Component_3Manager

Event

Component_4

Module_1

Component_1

Component_2

Event-driven. Практика

Проблема зоны видимости событий

Разные компоненты могут вызывать один и тот же эвент.

Module_2

Component_3Manager

Event

Component_4

Module_1

Component_1

Component_2

Event-driven. Практика

События привязаны к компонентам.

Некоторые события существуют вне компонентов (один элемент — один эвент — несколько компонентов).

  RequestSender = function( elem ){    this.$element = jQuery(elem);  }    RequestSender.prototype.complete = function(){    this.$element.trigger('js-form-update');  }    DynamicForm = function( elem ){    this.$element = jQuery(elem);  }

  DynamicForm.prototype.update= function(){    this.$element.trigger('js-form-update');  } 

Проблема зоны видимости событий

Разные компоненты могут вызывать один и тот же эвент.

Module_2

Component_3Manager

Event

Component_4

Module_1

Component_1

Component_2

Event-driven. Практика

Проблема именования событий

Имена событий — параметризуемые.

Module_2

Component_3Manager

Event

Component_4

Module_1

Component_1

Component_2

Event-driven. Практика

Как быть с дефолтными событиями?

Как быть с событиями конкретных компонентов?

Что делать с общими событиями?

  RequestSender = function( elem ){    this.$element = jQuery(elem);

    this.requestEvent = this.$element.data('requestEvent');    this.waitingDataEvent = this.$element.data('waitingDataEvent');    this.readyDataEvent = this.$element.data('readyDataEvent');  }

Проблема именования событийModule_2

Component_3Manager

Event

Component_4

Module_1

Component_1

Component_2

Event-driven. Практика

Имена события — параметризуемые.

Кто вызвал событие на компоненте?

Источник события — параметр события.

Module_2

Component_3Manager

Event

Component_4

Module_1

Component_1

Component_2

Event-driven. Практика

Каждому источнику — уникальноесобытие.

Передавать источник события.

  this.$element.trigger(    this.changeEvent,     {'eventSource' : 'filter'}  );

Кто вызвал событиена компоненте?

Module_2

Component_3Manager

Event

Component_4

Module_1

Component_1

Component_2

Event-driven. Практика

Источник события — параметр события.

Для кого предназначенособытие?

Источник события — параметр события.

Module_2

Component_3Manager

Event

Component_4

Module_1

Component_1

Component_2

Event-driven. Практика

Получатель — не всегда источник.

Каждому получателю — уникальное событие.

Передавать получателя.

this.$element.trigger(    this.readyEvent,     {'eventTarget' : this.$resultList});

Для кого предназначенособытие?

Module_2

Component_3Manager

Event

Component_4

Module_1

Component_1

Component_2

Event-driven. Практика

Источник события — параметр события.

Проблемы внутри компонента

Кто кого: метод вызывает событиеили же событие вызывает метод?

Module_2

Component_3Manager

Event

Component_4

Module_1

Component_1

Component_2

Event-driven. Практика

Событие предназначено для связывания компонентов.

Компонент слушает сам себя.

Кто кого: метод вызывает событиеили же событие вызывает метод?

Module_2

Component_3Manager

Event

Component_4

Module_1

Component_1

Component_2

Event-driven. Практика

  this._init = function(){      var context = this;        this.$element.on('js-clear', function(){      context.clearFields();    });  }  ИЛИ    this.clearFields = function(){    ...    this.$element.trigger('js-clear');  };

Проблемы внутри компонента

Кто кого: метод вызывает событиеили же событие вызывает метод?

Module_2

Component_3Manager

Event

Component_4

Module_1

Component_1

Component_2

Event-driven. Практика

  this._init = function(){      var context = this;        this.$element.on('js-do-clear', function(){      context.clearFields();    });  }    this.clearFields = function(){    ...    this.$element.trigger('js-complete-clear');  };

Проблемы внутри компонента

Event-driven. Итоги

Одинаково работают на любых проектах.—

Меньше зависимостей, больше гибкости.

Лучшая отказоустойстойчивость.

Сложность восприятия.

Большая вероятность появления «мусора».

Необходимость более тщательного проектирования приложения.

Забыть нельзя использовать

Вопросы?

Спасибо!

Антон ВеретенниковИлья Семаков