Паттерн Factory позволяет централизованно управлять созданием объектов, скрывая конкретные классы и предоставляя единый интерфейс для их генерации. В контексте Backbone.js это особенно полезно при работе с моделями, коллекциями и представлениями, когда тип создаваемого объекта может меняться динамически.
Backbone.js строится вокруг моделей, представляющих данные приложения. В крупных приложениях часто возникает необходимость создавать разные модели в зависимости от условий.
var ModelFactory = {
create: function(type, attributes) {
switch(type) {
case 'user':
return new UserModel(attributes);
case 'product':
return new ProductModel(attributes);
case 'order':
return new OrderModel(attributes);
default:
throw new Error('Unknown model type: ' + type);
}
}
};
// Примеры моделей
var UserModel = Backbone.Model.extend({
defaults: {
name: '',
email: ''
}
});
var ProductModel = Backbone.Model.extend({
defaults: {
title: '',
price: 0
}
});
var OrderModel = Backbone.Model.extend({
defaults: {
productId: null,
quantity: 1
}
});
// Использование фабрики
var user = ModelFactory.create('user', {name: 'Иван', email: 'ivan@example.com'});
var product = ModelFactory.create('product', {title: 'Ноутбук', price: 1000});
Ключевые моменты:
Backbone.js коллекции (Backbone.Collection) хранят
группы моделей одного типа. Использование фабрики упрощает создание
коллекций динамически.
var CollectionFactory = {
create: function(type, models) {
switch(type) {
case 'users':
return new UserCollection(models);
case 'products':
return new ProductCollection(models);
case 'orders':
return new OrderCollection(models);
default:
throw new Error('Unknown collection type: ' + type);
}
}
};
var UserCollection = Backbone.Collection.extend({
model: UserModel
});
var ProductCollection = Backbone.Collection.extend({
model: ProductModel
});
var OrderCollection = Backbone.Collection.extend({
model: OrderModel
});
// Создание коллекций через фабрику
var users = CollectionFactory.create('users', [user]);
var products = CollectionFactory.create('products', [product]);
Преимущества:
Backbone.js Views отвечают за отображение данных и взаимодействие с пользователем. В больших приложениях часто требуется динамическая генерация представлений.
var ViewFactory = {
create: function(type, options) {
switch(type) {
case 'user':
return new UserView(options);
case 'product':
return new ProductView(options);
case 'order':
return new OrderView(options);
default:
throw new Error('Unknown view type: ' + type);
}
}
};
var UserView = Backbone.View.extend({
tagName: 'div',
className: 'user',
render: function() {
this.$el.html('<strong>' + this.model.get('name') + '</strong>');
return this;
}
});
var ProductView = Backbone.View.extend({
tagName: 'div',
className: 'product',
render: function() {
this.$el.html(this.model.get('title') + ' — $' + this.model.get('price'));
return this;
}
});
// Использование фабрики для создания представлений
var userView = ViewFactory.create('user', {model: user});
var productView = ViewFactory.create('product', {model: product});
$('body').append(userView.render().el);
$('body').append(productView.render().el);
Особенности:
В сложных приложениях имеет смысл создать универсальную фабрику, которая будет создавать модели, коллекции и представления по одному интерфейсу:
var AppFactory = {
create: function(type, kind, options) {
var mapping = {
model: {
user: UserModel,
product: ProductModel,
order: OrderModel
},
collection: {
users: UserCollection,
products: ProductCollection,
orders: OrderCollection
},
view: {
user: UserView,
product: ProductView,
order: OrderView
}
};
var Class = mapping[kind][type];
if (!Class) throw new Error('Unknown ' + kind + ' type: ' + type);
return new Class(options);
}
};
// Примеры использования
var newUser = AppFactory.create('user', 'model', {name: 'Пётр'});
var newUsersCollection = AppFactory.create('users', 'collection', [newUser]);
var newUserView = AppFactory.create('user', 'view', {model: newUser});
$('body').append(newUserView.render().el);
Преимущества универсальной фабрики: