Заметки за апрель 2013 года

Коллекция разнотипных объектов в Backbone.js

В коллекциях Backbone.js не обязательно должны храниться объекты одного типа. Если в неё явно добавить экземпляр класса, унаследованного от Backbone.Model, то он без изменений будет помещён в неё. У коллекции есть атрибут model, в котором хранится конструктор модели. Когда в коллекцию добавляется простой объект, то он в качестве параметра передаётся в этот конструктор.

В атрибуте model можно, фактически, указать любую функцию. Возвращаемые значения (экземпляры классов, унаследованных от Backbone.Model) будут помещаться в коллекцию. Такие функции ещё называют фабриками или фабричными методами. В документации к атрибуту model как раз представлен вариант такой фабрики.

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

App.Factory = function (getter, hash, def) {
  return function () {
    var value = getter.apply(this, arguments);
    var ctor = hash[value] ? hash[value] : def;
    return new ctor(arguments[0], arguments[1]);
  };
};
  • getter — функция, которая возвращает значение, на основании которого будет выбираться требуемый конструктор;
  • hash — объект ключ-значение с перечислением конструкторов, которые могут использоваться фабрикой;
  • def — конструктор по-умолчанию.

Предположим, что в коллекции могут находиться объекты следующих классов:

App.Item = Backbone.Model.extend({});
App.ItemNews = App.Item.extend({});
App.ItemAction = App.Item.extend({});
App.ItemMessage = App.Item.extend({});

Таким образом, фабрика объектов будет выглядеть так:

App.ItemFactory = App.Factory(
  function (attr) { return attr.type; },
  {
    "news": App.ItemNews,
    "action": App.ItemAction,
    "message": App.ItemMessage
  },
  App.Item
);

App.Factory возвращает функцию, которая, в свою очередь, будет возвращать требуемый экземпляр в зависимости от значения атрибута type. Эту функцию и передаём в описание коллекции.

App.Items = Backbone.Collection.extend({
  model: App.ItemFactory
});

Теперь коллекция будет заполняться моделями нужного типа автоматически.

Практическое применение паттерна можно посмотреть в исходном коде примера.

Комментарии к заметке: 15

Ограничение скорости загрузки по сети

Мне для тестирования бывает нужно ограничить скорость HTTP-трафика для проверки того, как ресурс работает в тех или иных условиях.

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

Устанавливается он в систему с помощью npm:

npm install -g throttle-proxy

И запускается командой:

throttle-proxy

По-умолчанию, сервер будет слушать подключения на порту 3128 и ограничивать скорость до 100 тысяч байт в секунду. Эти значения можно поменять с помощью соответствующих параметров при запуске сервера.

throttle-proxy --speed 50000 --port 9999

Остановить прокси-сервер можно комбинацией клавиш Ctrl+C в консоли, где он запущен.

Не забудьте только указать адрес 127.0.0.1 и порт 3128 (или выбранный вами порт) в настройках системы в качестве HTTP-прокси сервера.

Исходный код доступен на GitHub — throttle-proxy

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

Комментарии к заметке: 4