Вступление
В то время когда компьютеры достаточно мощные — а разрабатываемые приложения — сложные, возникает желание (а иногда и потребность), в переносе большей части операций — на сторону пользователя.
Что позволяет как делать приложения с быстрым откликом и не зависеть от скорости интернета пользователя, так и снизить нагрузку непосредственно на сервера (особенно если они и так загружены по самое «небалуй»).
Но данное решение требует изначально правильного подхода к построению самого приложения.
Вот о таком варианте построения приложения — я и хочу рассказать.
Сервер
Клиент общается исключительно с API сервером, никакими генерациями страниц и подобным — сервер не занимается.
Всю ответственность за происходящее берёт на себя клиент.
Структура папок
Структура клиента построена таким образом — чтобы всё поведение — было крайне прозрачным и понятным.
Проект по структуре папок разделён на 3 части: библиотеки, модули и аддоны.
Библиотеки — это основные скрипты от которых в той или иной степени зависят все остальные, но сами могут зависеть только от подобных библиотек.
- JQuery и надстройки над ним
- элементы UI
- различные полифилы
- прочее
Под модулями подразумеваются основные части сайта, из которых по кусочками и собирается весь клиент.
Аддоны думаю понятно — это надстройки над основным функционалом.
Структура файлов
Файлы в структуре проекта тоже играют важную роль — имеется 6 видов файлов:
- *.boot.js — исполняет роль координатора для загрузчика модулей, в нём содержится информация о том — кто и когда должен быть загружен из данной папки.
- *.core.js — содержит в себе всю логику и исполняющие обязанности по управлению (содержимое в нём находится в области видимости core).
- *.interface.js — в интерфейсах содержится только управление внешним видом — с минимумом логики (содержимое в нём находится в области видимости interface).
- *.api.js — API интерфейс для общения клиента с сервером (доступен только модулям, содержимое находится в области видимости api)
- *.style.css — набор стилей для данного модуля/аддона
- *.js — скрипт в глобальной области видимости (используется очень редко, и только для библиотек)
Структура скрипта
Скрипты в нашем случае имеют 2 вида:
Класс — используется всегда когда необходимо: наследование и/или создание экземпляра.
var core = (function( core ) { with( core ) { core.NewClass = function( params ) { /** Какой-то код **/ return this; }; NewClass.prototype.func1 = function( ) { /** Какой-то код **/ return this; }; } return core; })( core || {} );
var class = new core.NewClass( params ); // можно не использовать core если находимся в той-же области видимости class.func1( );
Объект — используется во всех других случаях.
var core = (function( core ) { with( core ) { core.obj1 = { paramList: [], param1: 0, func1: function( ) { /** Какой-то код **/ return this; }, func2: function( ) { /** Какой-то код **/ return this; } } } return core; })( core || {} );
core.obj1.func1( ) // можно не использовать core если находимся в той-же области видимости .func2( );
Области видимости
У нас используются 3 области видимости не считая глобальной (которая используется иногда в библиотеках):
- api
- core
- interface
Разделение на области видимости позволяет нам удобно разделять поведение, и не парится с возможным пересечением названия функций и прочего:
var interface = (function( interface ) { with( interface ) { interface.NewClass = function( params ) { /** Создаём интерфейс **/ }; NewClass.prototype.show = function( ) { /** Показываем интерфейс **/ return this; }; NewClass.prototype.hide = function( ) { /** Скрываем интерфейс **/ return this; }; } return core; })( core || {} );
var core = (function( core ) { with( core ) { core.NewClass = function( params ) { this.interface = new interface.NewClass( ); }; NewClass.prototype.show = function( ) { this.interface.show( ); /** Производим манипуляции с интерфейсом после его показа **/ return this; }; NewClass.prototype.hide = function( ) { /** Производим манипуляции с интерфейсом до его скрытия **/ this.interface.hide( ); return this; }; } return core; })( core || {} );
Ну и разделение на области видимости (и такой ООП подход) также позволяет лучше придерживаться парадигмы: никакой из модулей не должен знать о другом, пока в этом нет жёсткой необходимости.
Помогает в этом правильная реализации bind`ов на выполнение функций (у нас есть возможность влезать как в начало функции, так и в конец, с возможностью прерывания её выполнения или-же модификации данных).
Но об этом — в следующий раз.
ссылка на оригинал статьи http://habrahabr.ru/post/217971/
Добавить комментарий