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

ссылка на оригинал статьи http://habrahabr.ru/post/217971/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *