Backbone.js предоставляет мощный, но при этом легковесный подход к построению клиентских приложений на JavaScript. Важной частью архитектуры являются модели (Models) — объекты, представляющие данные и логику приложения. Для удобного создания и тестирования моделей часто применяются factories и builders, позволяющие стандартизировать процесс генерации экземпляров с предопределёнными данными и зависимостями.
Каждая модель в Backbone наследуется от Backbone.Model и
может определять атрибуты по умолчанию, методы для
валидации и события:
var User = Backbone.Model.extend({
defaults: {
name: "Имя пользователя",
email: "",
role: "guest"
},
validate: function(attrs) {
if (!attrs.email.includes("@")) {
return "Email должен содержать символ @";
}
}
});
Ключевые возможности модели:
change,
sync, destroy и другие.get,
set, toJSON, save,
fetch, destroy.Model Factory — это функция или объект, предназначенный для создания экземпляров моделей с заранее заданными свойствами. Использование фабрик упрощает:
Простейшая фабрика может выглядеть так:
function userFactory(overrides) {
var defaults = {
name: "Новый пользователь",
email: "user@example.com",
role: "guest"
};
var attributes = Object.assign({}, defaults, overrides);
return new User(attributes);
}
var admin = userFactory({ role: "admin", name: "Администратор" });
Преимущества фабрики:
Builder — более гибкая и расширяемая структура, чем простая фабрика. Он позволяет поэтапно настраивать объект, комбинируя методы конфигурации перед созданием экземпляра модели.
Пример Builder для модели User:
function UserBuilder() {
this.attrs = {
name: "Новый пользователь",
email: "user@example.com",
role: "guest"
};
}
UserBuilder.prototype.withName = function(name) {
this.attrs.name = name;
return this;
};
UserBuilder.prototype.withEmail = function(email) {
this.attrs.email = email;
return this;
};
UserBuilder.prototype.withRole = function(role) {
this.attrs.role = role;
return this;
};
UserBuilder.prototype.build = function() {
return new User(this.attrs);
};
// Использование
var manager = new UserBuilder()
.withName("Менеджер проекта")
.withEmail("manager@example.com")
.withRole("manager")
.build();
Ключевые особенности Builder-подхода:
Для тестирования часто необходимо создавать множество моделей с уникальными атрибутами. Можно комбинировать фабрики и builders с генераторами случайных данных:
function randomEmail() {
return `user${Math.floor(Math.random() * 1000)}@example.com`;
}
function randomUserFactory() {
return new User({
name: `User${Math.floor(Math.random() * 1000)}`,
email: randomEmail(),
role: "guest"
});
}
var users = [];
for (var i = 0; i < 10; i++) {
users.push(randomUserFactory());
}
Фабрики и builders особенно полезны при работе с Backbone.Collection. Коллекция может быть автоматически заполнена моделями, созданными фабриками:
var Users = Backbone.Collection.extend({
model: User
});
var usersCollection = new Users();
for (var i = 0; i < 5; i++) {
usersCollection.add(userFactory({ name: `User ${i + 1}` }));
}
В тестах Model factories позволяют:
Пример теста с использованием фабрики:
describe("User model", function() {
it("should validate email correctly", function() {
var invalidUser = userFactory({ email: "invalidEmail" });
var validationError = invalidUser.validate(invalidUser.attributes);
console.assert(validationError === "Email должен содержать символ @");
});
});
В сложных проектах часто применяют гибридный подход, где фабрика отвечает за базовые атрибуты, а builder позволяет добавлять специфические конфигурации:
function userFactoryWithBuilder(overrides) {
var builder = new UserBuilder();
if (overrides.name) builder.withName(overrides.name);
if (overrides.email) builder.withEmail(overrides.email);
if (overrides.role) builder.withRole(overrides.role);
return builder.build();
}
Такой подход обеспечивает масштабируемость и гибкость при генерации моделей в больших приложениях.
Использование Model factories и builders в Backbone.js:
Эти инструменты являются ключевыми при построении модульных, поддерживаемых и легко тестируемых клиентских приложений.