Статьи

Организация приложений уровня предприятия

Организация может сделать или нарушить ремонтопригодность приложения. С небольшими приложениями организация становится более очевидной; однако по мере роста приложения и увеличения числа разработчиков приложений и внешних разработчиков, создающих код, становится все более запутанной организация. В этой статье мы рассмотрим некоторые основные концепции организации приложений, чтобы поиск соответствующего кода был эффективным и систематическим процессом.


JavaScript должен быть эффективен.

Давайте на минутку рассмотрим, как команды Rails и WordPress организуют свои проекты. Скорее всего, вы, вероятно, работали с одним или другим из них. Обе платформы имеют заданную структуру по умолчанию.

При создании приложения Rails Rails обрабатывает большую часть основных потребностей организации. Поскольку он основан на MVC, в настройках Rails по умолчанию есть папка с названием «app», которая содержит папки model / view / controller. Он также предоставляет «помощники» и «почтовики», расширения контроллера, которые помогают заполнить пробелы между контроллерами и моделями.

Rails также генерирует несколько других элементов на том же уровне, что и папка «app», таких как конфигурация, ведение журнала, базы данных, временное / кэширование, тесты и некоторые другие части. Что особенно интересно в этом обсуждении — это приложение и общие папки. Общая папка служит источником статических ресурсов, включая любые не динамические файлы HTML, CSS и JavaScript.

При работе с WordPress названия и структура гораздо менее очевидны.

… приложение создано для пользователей …

Условные обозначения представлены в виде документации. В частности, разработчики, скорее всего, работают внутри темы, расположенной в каталоге wp-content / themes /. Эта тема имеет массив файлов со специальными именами, в основном на основе представлений. Файл functions.php выступает в качестве своего рода «контроллера», где разработчик может поместить функции, чтобы отделить их от представлений. Тем не менее, WordPress темы часто омрачают воду между логикой и презентацией. Например, запросы к базе данных неявны по имени файла, но часто ими манипулируют, изменяя запрос перед циклическим просмотром возвращаемых результатов. Эта манипуляция не абстрагируется так же, как контроллер (и, конечно, WordPress не находится рядом с MVC, поэтому мы не можем ожидать такого типа организации).

Обе эти платформы чрезвычайно популярны, и обе используют свое неявное структурирование. Они абсолютно требуют, чтобы разработчики понимали, как система работает, чтобы быть эффективной. В наших собственных приложениях мы должны учитывать эту организационную парадигму и создавать системный подход к структурированию приложений. Это играет очень по-разному для каждого отдельного приложения.


Платформы, упомянутые выше, не требуют от разработчиков определения структуры; они «предварительно подключены» для работы определенным образом.

Одна важная причина, по которой надежные структуры часто абстрагируют эти конфигурации и предоставляют структуры по умолчанию, состоит в том, что люди начинают разрабатывать стандарты сообщества, основанные на структуре по умолчанию.

Не игнорируйте стандарты при организации вашего приложения!

Если вы знакомы с Rails, вы, скорее всего, можете взглянуть на репозиторий Github и узнать, является ли оно приложением Rails, просто по структуре папок — у Rails есть документированный стандарт.

Не игнорируйте стандарты при организации вашего приложения! Весьма вероятно, что если вы организуете приложение уровня предприятия, то имеете дело с модульными, мини-приложениями на основе сервисов. Например, это может быть случай, когда у вас есть несколько приложений, созданных с использованием одной или нескольких различных платформ, или они могут быть свернуты вручную и работать совместно друг с другом, предоставляя API, которые предоставляют хуки для других сервисов. Каждое из этих отдельных приложений, вероятно, соответствует стандартам структуры, на которой оно было построено; эти стандарты существуют, потому что они — способ, которым эта структура была разработана, чтобы работать. Если вы попытаетесь изменить эти стандарты в отдельном приложении, вы, скорее всего, потратите больше времени на настройку, чем на фактическое создание работающего приложения.


На практике это означает, что объекты, которые предоставляются из одной службы в другую, должны работать единообразно, а части, которые являются внутренними для службы, должны работать так, как это лучше всего подходит для данной конкретной службы, вероятно, с помощью какой-либо инфраструктуры или технологический стек, на котором работает служба.

Помните, в конце концов, приложение создано для пользователей, и пользователи не знают или не ценят разделение отдельных сервисов.

Вместо этого они понимают приложение и опыт как одно целое, и что одно изделие выиграет, прежде всего, от однородности на верхнем уровне.

Так что же должно быть однородным?

по мере роста приложения … становится более запутанной организация.

Маршруты (структуры URL) являются одним из наиболее важных определяющих факторов работы веб-приложения. Важно, чтобы ваши маршруты следовали единой структуре. Например, при отображении «учетной записи пользователя» с URL-адресом, подобным /user/5 где 5 — это целочисленный идентификатор первичного ключа пользователя, вам не следует использовать множественное число для другого единственного объекта, такого как /widgets/16 . Вместо этого он должен быть /widget/16 . Это не только помогает разработчикам быть последовательными, но также обеспечивает ясность и единообразие для пользователей. Неважно, что вы выберете для своей структуры маршрута, если она согласована на уровне пользователя.

Это очень важно для внутренней разработки, и еще более важно для разработки программного продукта / услуги, где API открыт для общественности. Если ваши вызовы API имеют подчеркивания в качестве разделителей слов, не используйте CamelCase или разделенный дефисом ключ в вашем API где-либо еще. Если вы используете слово «count» для обозначения «вернуть это количество объектов», не используйте что-то вроде «count_per_page» для обозначения того же самого в другом месте в том же (или связанном) API. Это небрежный дизайн API. Разработайте стандартный синтаксис и придерживайтесь его; обратите внимание, что об этом часто заботится хорошо выполненный дизайн маршрута в API REST.

На общем уровне, когда вы имеете дело с «виджетами foo» (произвольными объектами или действиями) в вашем приложении, убедитесь, что вы используете одну и ту же терминологию во всех своих приложениях. Например, хотя в Rails может быть обычной практикой использование «публичного» каталога, у вас есть контроль над тем, что внутри него.

Не используйте папку «js» для одного фреймворка и папку «scripts» для другого фреймворка.

Не называйте модели данных «orange_items» в одной среде и «OrangeItems» в другой, если только язык или среда явно не требуют этого по функциональной причине. Даже тогда убедитесь, что существует согласованная система и «грамматика», и убедитесь, что различия между отдельными сервисами хорошо документированы и обоснованы . Подобные сигналы и единообразие значительно помогут в понимании классификации объектов в приложении.

Зеркальное отображение маршрутов к папкам и файлам очень помогает поддерживать организованность приложения. Например, у вас могут быть папки для CSS, JavaScript и изображений внутри ваших «публичных» или «статических» папок. Создание структуры папок, которые сопоставляются с вашими маршрутами, представлениями, контроллерами или другими подобными структурами, может помочь сохранить ваш CSS модульным. Затем вы можете использовать такой инструмент, как CodeKit, чтобы объединить эти файлы в один уменьшенный файл. Конечно, у вас также может быть global.css для правил, которые применяются ко всему приложению. Ниже приведен пример (.rb для Ruby, но это может пойти для любой структуры фреймворка MVC).

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
— root/
— app/
— models/
—- foo.rb
—- bar.rb
—- baz/
—— widget.rb
— views/
—- global.html.erb
—- foo.html.erb
—- bar.html.erb
—- baz/
—— widget.html.erb
— controllers
—- foo.rb
—- bar.rb
— public
— CSS
— global.css
— foo.css
— bar.css
— baz/
—- widget.css
— JS
— global.js
— foo.js
— bar.js
— baz/
—- widget.js
— Images/
— global/
—- image.jpeg
— foo
—- image.jpeg
— bar
—- image.jpeg
— baz/
—- widget/
—— image.jpeg

Можно быстро увидеть, что не составит труда найти конкретные CSS, JavaScript, модели и т. Д. Для определенного раздела приложения.

Маршруты (структуры URL) являются одним из наиболее важных определяющих факторов работы веб-приложения.

Лучший способ подумать об этом — разделить ваши файлы на «области» вашего сайта. Например, возможно, у вас есть приложение, которое включает в себя область «администратора» и область «профиля». Вы можете создать файл global.css для хранения объектов / правил, которые применяются к обеим областям (включая сброс, некоторые правила типографии, цвета и т. Д.), А затем создать специальные файлы, которые применяются к отдельным областям для правил стиля содержимого, которые не ‘ т поделился. Таким образом, поскольку разработчик работает над определенной страницей, он останется в одном или двух файлах и будет точно знать, где найти нужные файлы.

Другой эффективный способ контролировать ваши статические файлы — давать им имена в зависимости от того, что они делают. Например, создайте reset.css , typography.css , colors.css , colors.css и т. Д. У этого метода есть свои плюсы и минусы, особенно для CSS. Это держит ваш CSS сосредоточенным на правилах представления; однако, вероятно, потребуется повторять селекторы для нескольких файлов, открывая их заново для определения различных типов правил стиля. Единственный способ избежать этого — называть ваши классы / идентификаторы только по стилю, а не по семантике, например, class="green-text five-columns medium-shadow" . В противном случае вы в конечном итоге сделаете что-то вроде этого:

В typography.css

1
2
3
4
5
6
7
8
.semantic-widget {
    color: #232323;
    text-shadow: 1px 1px #fff;
    font-size: 1.2em;
    line-height: 1.1em;
    font-family: sans-serif;
    font-weight: 300;
}

В dimensions.css

1
2
3
4
5
.semantic-widget {
    width: 20%;
    margin: 0 2.5%;
    padding: 10px;
}

Что, конечно, не так сухо, как это возможно.

Организация небольших приложений (с меньшим количеством этих объектов-виджетов) может по-прежнему выигрывать от разделения по типу правила.

Однако, если у вас есть приложение, которое имеет много разных типов объектов, областей приложения и т. Д., Вам, вероятно, следует выбрать разделение ваших CSS-файлов на области (стратегия зеркалирования, которую мы обсуждали выше).

Присвоение имен файлам JavaScript по их функциям немного более выполнимо, но только если вы используете триггеры событий (модель pub / sub). Рассмотрим следующий пример:

1
2
3
$.getJSON(«/messages/all.json», function(data){
    // do some stuff
});

Вы можете сделать несколько вещей в этом обратном вызове. Вы можете отправить уведомление пользователю и обновить список сообщений. Если ваши файлы разделены по функциональности, у вас могут быть файлы notifications.js и messages.js которые обрабатывают эти конкретные функции. Внутри обратного вызова для этого AJAX-вызова JSON вы «опубликуете» событие для остальной части приложения. Затем внутри ваших файлов уведомлений и сообщений вы можете «подписаться» на событие и ответить соответствующим образом.

в events.js :

1
2
3
$.getJSON(«/messages/all.json», function(messages){
    $(«body»).trigger(«received_messages», messages);
});

в messages.js :

1
2
3
$(«body»).on(«received_messages», function(event, messages){
    // iterate through messages and append to a list
});

в notifications.js

1
2
3
4
5
6
$(«body»).on(«received_messages», function(event, messages){
    // send_notification may be a local function that allows you to send notifications
    // to the user, along with a notification type, an integer;
    // case, «1» may simply mean to style the notification as a «success» alert
    send_notification(«Succesfully Received Messages!», 1);
});

Есть несколько вещей, которые нужно помнить о ваших статических файлах. В этой статье предполагается, что вы будете объединять статические файлы соответствующим образом. Но что именно уместно?

Крис Койер недавно заявил, что ни одному приложению не нужно больше трех CSS-файлов. В искаженном формате он утверждает, что большинству сайтов, которые имеют одну страницу или много похожих страниц, нужен один файл CSS. Приложениям, которые имеют разные «разделенные» разделы, требуется один файл CSS для глобальных элементов и один файл для конкретных разделов. Наконец, очень сложным сайтам нужны три файла (глобальный, специфичный для раздела и одноразовый css). Крис имеет в виду файлы, которые загружаются в голову (не обязательно то, что вы разрабатываете), так что это будут ваши объединенные файлы.

Итак, зачем вы это делаете, спросите вы? В первую очередь, чтобы воспользоваться кешем браузера.

Например, объединение на лету не позволяет использовать кеш браузера. Другое преимущество этого подхода — загрузка только того, что вам нужно. Если у вас есть целый раздел «admin», который 95% ваших пользователей никогда не видят, им не нужно загружать CSS для этого раздела.

Разработайте стандартный синтаксис и придерживайтесь его.

Подобно CSS, JavaScript должен быть эффективен.

Прибыль всегда следует тщательно контролировать; если ваш javascript достаточно мал, чтобы оправдать объединение в один скрипт, во что бы то ни стало, не стесняйтесь загружать модульный JavaScript в ваш конечный продукт.

Как кратко упомянуто выше, если количество пользователей, попадающих на определенную страницу, незначительно, не помещайте CSS / JS в статические файлы вашего глобального приложения. Административные статические файлы также должны оставаться отдельными. Если ваше приложение поддерживает учетные записи пользователей, рассмотрите возможность исключения статических файлов для неавторизованной (маркетинговой) стороны приложения. Как только пользователь входит в систему, он уже принял на себя обязательство принять участие во всем, что предоставляет ваше приложение. Первые впечатления — это все, и загрузка нескольких неиспользуемых CSS и JavaScript только ухудшит производительность первого впечатления.


Если вы действительно используете структуру, используйте существующую структуру этой структуры. Если ваша структура не имеет существующей структуры или очень простой структуры (прекрасными примерами этого являются Sinatra и CodeIgniter), рассмотрите возможность зеркального отражения структуры других компонентов в приложении. Если вы начинаете с нуля, посмотрите на другие проекты, которые люди завершили как в используемой вами среде, так и в других средах, использующих тот же язык. Например, если выбранный вами фреймворк работает на MVC, но не имеет конфигураций по умолчанию для размещения этих частей, вполне вероятно, что существует соглашение об именах, в котором используются ключевые слова Model, View и Controller.

Когда дело доходит до этого, организация на уровне предприятия состоит из четырех основных вещей:

  1. Быть последовательным; разработать внутренние, общепринятые соглашения.
  2. Следуйте рамочным / общественным соглашениям, когда это возможно и когда необходимо.
  3. Сделайте логичный, самодокументированный выбор.
  4. Документируйте свой выбор и убедитесь, что несоответствия в системе или с соглашениями раскрыты и известны всем, кто работает над программным обеспечением.