...

среда, 2 апреля 2014 г.

[Из песочницы] Наш вариант подхода к написанию JS приложений

Хочу поделиться с Вами нашим ( о том кто такие МЫ — я смогу рассказать несколько позже ) вариантом подхода к написанию клиентского JS приложения.



Вступление



В то время когда компьютеры достаточно мощные — а разрабатываемые приложения — сложные, возникает желание (а иногда и потребность), в переносе большей части операций — на сторону пользователя.

Что позволяет как делать приложения с быстрым откликом и не зависеть от скорости интернета пользователя, так и снизить нагрузку непосредственно на сервера (особенно если они и так загружены по самое «небалуй»).

Но данное решение требует изначально правильного подхода к построению самого приложения.

Вот о таком варианте построения приложения — я и хочу рассказать.



Сервер



Клиент общается исключительно с 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`ов на выполнение функций (у нас есть возможность влезать как в начало функции, так и в конец, с возможностью прерывания её выполнения или-же модификации данных).

Но об этом — в следующий раз.

This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий