Картинка привлечения внимания!

Паттерны JavaScript

Простые решения стандартных задач

Зовите меня КЭП

Что такое паттерн?

  1. Выверенное решение
  2. Легко используются повторно
  3. Формируют структуру

В JS паттерны
не прижились?

Почему?

  1. У меня простые задачи, зачем усложнять?
  2. Мы ищем оптимальное решение для каждой задачи
  3. ООП в JS и паттерны дают более ресурсоемкие решения

Ну почему же?

  1. За паттерны надо наказывать!
    Для начинающих это «взрыв мозга», а опытным — не нужно.
  2. Мы позволяем нашим разработчикам самим решать: использовать или не использовать паттерны
  3. Паттерны? Какие паттерны?

Ну и зачем мне использовать паттерны?

  1. Проверены множеством людей, что может уберечь от ошибок
  2. Не требуют дополнительного времени на написание велосипеда
  3. Формируют четкую и узнаваемую структуру кода
  1. Обеспечивают предсказуемость кода
  2. Упрощают поддержку и расширяемость кода
  3. Упрощают подключение новых людей к проекту

А почему вы,
да-да, вот вы,
не используете паттерны?

Те, кто решил
не использовать паттерны могут выпить кофе и вздремнуть

Базовые понятия

Типы данных:

  1. Number
  2. String
  3. Boolean
  4. null
  5. undefined
  6. Object

Функции:

  1. Декларативные
    function foo(){}
  2. Выражения
    var foo = function(){};
  3. Созданные конструктором function
    var foo = new Function();

Функции могут быть:

  1. Самовызывающимися
    (function (){})();
  2. Конструкторами
    function Constructor(){}
    var newObj = new Constructor;

Конструктор

Все объекты порождаются конструкторами

Прототипы

  1. Объект, служащий прообразом для других объектов.
  2. Есть у всех объектов.
  3. Прототипом может быть либо объект, либо null.
function Constructor(){
  this.firstMethod = function(){};
}
Constructor.prototype.secondMethod = function(){};
var newObj = new Constructor;

Ссылки для изучения

Паттерны
(Наконец-то)

Модуль

Задачи:

  1. Инкапсуляция
  2. Создание четкой структуры из подключаемых модулей
  3. Прекратить засорять глобальный контекст
(function(){
/*Наш код*/
})();
(function(
  global, 
  window, 
  document, 
  undefined){
  function Module(){
    /*Наш код*/
    console.log(global); //window
    console.log(window); //window
    console.log(document); //#document
    console.log(undefined); //undefined
  }
  global.ourModule = new Module;
})(this, window, window.document);
(function(global){
  function Module(){
    var privateVar = 0;
    return {
      getPrivateVar: function(){
        return privateVar;
      }
    }
  }
  global.ourModule = new Module;
})(this);
console.log(typeof window.ourModule.privateVar); 
  //undefined
console.log(typeof window.ourModule.getPrivateVar); 
  //function
console.log(window.ourModule.getPrivateVar()); 
  //0

Ссылки для изучения

Логотип
Логотип

Одиночка

Задачи:

  1. Ограничить количество экземпляров класса одним
  2. При повторном вызове конструктора возвращать ссылку на созданный ранее экземпляр класса

Но в JS нет классов…

var a = {};
var b = {};
console.log(a==b); //false
console.log(a===b); //false

Применим синглтон
к модулю

(function(global){
  function Singleton(){
    /*Наш код*/
  }
  firstSingleton = new Singleton;
  secondSingleton = new Singleton;
})(this);
console.log(firstSingleton===secondSingleton); //false

Где сохранить ссылку на экземпляр класса?

  1. В статическом свойстве
  2. В замыкании
(function(global){
  function Singleton(){
    var instance = this;
    Singleton = function () {
      return instance;
    }
  }
  firstSingleton = new Singleton;
  secondSingleton = new Singleton;
})(this);
console.log(firstSingleton===secondSingleton); //true
(function(global){
  function Singleton(){
    var instance = this;
    Singleton = function () {
      return instance;
    }
  }
  firstSingleton = new Singleton;
  Singleton.prototype.newProperty = true;
  secondSingleton = new Singleton;
})(this);
console.log(firstSingleton===secondSingleton); //true
console.log(firstSingleton.newProperty); //undefined
console.log(secondSingleton.newProperty); //undefined
(function(global){
  function Singleton(){
    var instance = this,
        prototype = Singleton.prototype;
    Singleton = function () {
      return instance;
    }
    Singleton.prototype = prototype;
    Singleton.constructor = Singleton;
    instance.constructor = Singleton;
    return instance;
  }
  firstSingleton = new Singleton;
  Singleton.prototype.newProperty = true;
  secondSingleton = new Singleton;
})(this);
console.log(firstSingleton===secondSingleton); //true
console.log(firstSingleton.newProperty); //true
console.log(secondSingleton.newProperty); //true

Ссылки для изучения

Логотип
Логотип

Наблюдатель

Задачи:

При изменении состояния одного из объектов оповещать об этом «подписанные» на это событие объекты

(function(global){
  function Observable(){}
  function Observer(){}
})(this);
function Observer(){}
Observer.prototype.tweet = function(data){};
function Observable(url){
  this.subscribers = {};
  this.dataUrl = url;
}
Observable.prototype.subscribe = function(event, observer, callback){};
Observable.prototype.unsubscribe = function(event, observer){};
Observable.prototype.publish = function(data, event){};
Observable.prototype.load = function(){};
Observable.prototype.loaded = function(data){};
Observable.prototype.load = function(){
  $.ajax({
    url: this.dataUrl,
    success: $.proxy(this.loaded,this)
  });
};
Observable.prototype.loaded = function(data){
  this.publish(data,'dataLoaded')
};
Observable.prototype.subscribe = function(event, callback){
  if(this.subscribers.hasOwnProperty(event)){
    var index = this.subscribers[event].length;
    while(index--){
      if(this.subscribers[event][index] == callback){
        return false;
      }
    }
    this.subscribers[event].push(callback);
  }else{
    this.subscribers[event]=[callback]
  }
  return true;
};
Observable.prototype.unsubscribe = function(event, callback){
  if(this.subscribers.hasOwnProperty(event)){
    var index = this.subscribers[event].length;
    while(index--){
      if(this.subscribers[event][index] == callback){
        this.subscribers[event].splice(index,1);
        return true;
      }
    }
  }
  return false;
};
Observable.prototype.publish = function(data, event){
  if(this.subscribers.hasOwnProperty(event)){
    var index = this.subscribers[event].length;
    while(index--){
      this.subscribers[event][index](data);
    }
    return true;
  }
  return false;
};
global.observer = new Observer;
global.observable = new Observable('http://test.com/data/');
global.observable.subscribe('dataLoaded', global.observer.tweet);
global.observable.load();

Ссылки для изучения

Логотип
Логотип

Паттерны JavaScript решают множество задач. Что дальше?

JavaScript

Шаблоны

Стоян Стефанов

ISBN 978-5-93286-208-7русскийбумажная

ISBN 978-0-596-80675-0английскийбумажная

ISBN 978-0-596-80677-4английскийэлектронная

Market.ya.ru: http://goo.gl/bXuSk

Amazon.com: http://goo.gl/FI5Eg

Learning

JavaScript

Design Patterns

Addy Osmani

ISBN 978-1-4493-3181-8английскийбумажная

ISBN 978-1-4493-3486-4английскийэлектронная

Litres.ru http://goo.gl/4E1De

Amazon.com: http://goo.gl/gVH6X

Читать OnLine: http://goo.gl/wEKPU

Design Patterns:

Elements of Reusable Object-Oriented Software

Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides

ISBN 978-0-201-63361-0английскийбумажная

ISBN 978-5-469-01136-1русскийбумажная

Market.ya.ru: http://goo.gl/G1du7

Amazon.com: http://goo.gl/PUKLB

Читать OnLine: http://goo.gl/lfRgk

Иллюстрации бессовестно одолжены у McBess

Вы можете
найти еще на mcbess.com

Немедленно
спросите меня
о чем-нибудь

vcard

Антон Немцев

anton@websaints.net

@silentimp

skype: ravencry