Код организации в крупных AngularJS и JavaScript приложений
Многие разработчики борются с тем, как организовать код базировать приложения, когда он увеличивается в размерах. Я видел это недавно в приложениях AngularJS и , но исторически это была проблема с всеми технологиями, включая многие приложения Java и Flex, над которыми я работал в прошлом.
Общая тенденция - одержимость организацией вещей по типу. Это имеет поразительное сходство с тем, как люди организуют свою одежду .
Сваи на полу
Давайте посмотрим на угловом семени, официальной отправной точкой для AngularJS приложений. Каталог "приложение" содержит следующую структуру:
CSS/IMG/JS/app.js controllers.js directives.js filters.js services.js Библиотека/обертоны/каталог JavaScript имеет один файл для каждого типа объекта мы пишем. Это очень похоже на организацию вашей одежды на разных сваях на полу. У вас есть куча носков, нижнее белье, рубашки, брюки и т. Д. Вы знаете, что ваши черные шерстяные носки находятся в , которые кучу в углу, но это займет некоторое время, чтобы выкопать их .
Это беспорядок. Люди не должны так жить, и разработчики не должны кодировать это. После того, как вы получите за полдюжины или так диспетчеров или услуги, эти файлы становятся громоздкими: объекты вы ищете трудно найти, файл изменения целиком в системе управления версиями становятся непрозрачным и т.д.
носка Выдвижных
Следующий логический проход при организации JavaScript включает в себя создание каталога для некоторых архетипов и разбиения объектов на их собственные файлы . Чтобы продолжить метафору одежды, мы теперь вложили в симпатичный комод мохагони и планируем положить носки в один ящик, нижнее белье в другое, и аккуратно складываем наши штаны и рубашки в других.
Предположим, мы создаем простой сайт электронной коммерции с логином поток, каталог продуктов и пользовательский интерфейс корзины покупок. Мы также определили новые архетипы для моделей (бизнес-логику и состояние) и сервисов (прокси для конечных точек HTTP/JSON), а не привязали их к одиночному «сервисному» архетипу. Наш каталог JavaScript теперь может выглядеть следующим образом:
контроллеры/LoginController.js RegistrationController.js ProductDetailController.js SearchResultsController.js directives.js filters.js модели/CartModel.js ProductModel.js SearchResultsModel.js UserModel.js услуги/CartService.js UserService.js ProductService.js Ницца! Теперь объекты можно легко найти, просмотрев файлное дерево или с помощью ярлыков IDE, изменения в элементе управления источника теперь четко указывают , что было изменено и т. Д.Это значительное улучшение, но по-прежнему страдает от некоторых ограничений.
Представьте, что вы находитесь в офисе и понимаете, что вам нужно несколько нарядов уборка перед ужином для деловой поездки завтра утром. Вы звоните домой и попросите вашего значительного другого взять черный уголь и синие костюмы с полосками для чистящих средств. И не забывайте, что серая рубашка с черным пейсли-галстуком и белой рубашкой с твердым желтым галстуком. Представьте себе, что ваш существенный другой совершенно не знаком с вашим гардеробом и гардеробом . Когда они просеивают ваш галстук, они видят три желтых галстука. Какой из них выбрать?
Было бы неплохо, если бы ваша одежда была организована снаряжением? В то время как существуют практические ограничения, такие как стоимость и пространство, которые делают этот сложным с одеждой в реальном мире, что-то подобное может быть сделано с кодом при нулевой стоимости.
Модульность
Надеюсь банальные метафоры не слишком утомительно, но вот резюмировать:
Ваша вторая половинка является новым разработчиком в команде, кто был просят исправить ошибку на одном из многие экраны в вашем приложении. Разработчик просеивает структуру каталогов и видит все аккуратно организованные контроллеры, модели и сервисы . К сожалению, ничего не говорит о том, какие объекты связаны или имеют зависимости . Если в какой-то момент разработчик хочет, чтобы повторно использовал некоторый код, им нужно собирать файлы из группы разных папок и неизменно забывать код из другой папки где-то в другом месте. Верьте или нет, вам редко приходится повторно использовать все контроллеров из приложения электронной коммерции в новом приложении для создания отчетов , которое вы строите. Однако вам может потребоваться повторное использование некоторых из логики аутентификации . Было бы неплохо, если бы все было в одном месте? Давайте реорганизовать приложение на основе функциональных областей:
корзина/CartModel.js CartService.js общий/directives.js filters.js продукт/поиск/SearchResultsController.js SearchResultsModel.js ProductDetailController.js ProductModel.js ProductService.js user/ LoginController.js RegistrationController.js UserModel.js UserService.js Любой случайный разработчик может теперь открыть папку верхнего уровня и сразу получить представление о том, что делает приложение. Объекты в той же папке имеют отношения, а некоторые будут иметь зависимости на других. Понимание того, как работает процесс регистрации и регистрации , так же просто, как просмотр файлов в этой папке. Примитивное повторное использование через копия/вставка, по крайней мере, может быть выполнена путем копирования папки в другого проекта.
С AngularJS мы можем принять это шаг вперед и создать модуль этот связанный код:
1 2 3 4 5 6 7 8 9 10 11 12 13 уаг userModule = angular.module ('userModule », []); userModule.factory ('userService', ['$ http', function ($ http) {вернуть новый UserService ($ http);}]);
пользовательModule.factory ('userModel', ['userService', function (userService) {вернуть новый UserModel (userService);}]);
userModule.controller ('loginController', ['$ scope', 'userModel', LoginController]); userModule.controller ('registrationController', ['$ scope', 'userModel', RegistrationController]); view rawUserModule.js, размещенный с помощью ❤ от GitHub. Если мы поместим UserModule.js в пользовательскую папку, он станет «манифестом» объектов , используемых в этом модуле. Это также было бы разумным местом для , чтобы добавить некоторые директивы загрузчика для RequireJS или Browserify.
Советы для общего кода
Каждое приложение имеет общий код, который используется многими модулями. Нам нужно только место для него, которое может быть папкой с именем «common» или «общий» или что угодно. В действительно больших приложениях существует , чтобы быть много перекрытия функциональности и сквозных проблем. Это можно сделать управляемым с помощью нескольких методов:
Если объекты вашего модуля требуют прямого доступа к нескольким «общим» объектам , напишите один или несколько Фасадов для них. Это может помочь уменьшить число коллабораторов для каждого объекта, так как у них слишком много коллаборационистов, как правило, является запахом кода. Если ваш «общий» модуль становится большим, разделите его на подмодули, которые адресуют конкретную функциональную область или проблему. Убедитесь, что ваши прикладные модули используют только «общие» модули, в которых они нуждаются. Это вариант «Принципа сегрегации интерфейса » от SOLID. Добавьте методы утилиты на $ rootScope , чтобы они могли использоваться дочерними областями. Это может помочь предотвратить наличие проводки той же зависимости (например, «PermissionsModel») в каждый контроллер в приложении. Обратите внимание, что это должно выполняться экономно , чтобы избежать загромождения глобальной области и сделать зависимости неочевидным. Используйте события для развязки двух компонентов, которые не требуют ссылки . AngularJS делает это возможным с помощью методов $ emit, $ broadcast и $ on объекта Scope. Контроллер может запустить событие для выполнения какого-либо действия, а затем получить уведомление о завершении действия. Быстрое примечание по активам и испытаниям
Я думаю, что существует больше возможностей для гибкости при организации HTML, CSS и изображений. Размещение их в подпапке «активы» модуля , вероятно, наносит лучший баланс между инкапсуляцией зависимостей активов модуля , а не слишком большими помехами. Однако я думаю, что отдельная папка верхнего уровня для этого контента, которая содержит структуру папок, которая отражает структуру пакета приложения , тоже разумна. Я думаю, что это хорошо работает и для тестов.
Я думаю, что полный пример здесь http://ify.io/using-requirejs-with-optimisation-for-lazy-loading-angularjs-artefacts/ – Shohel
Спасибо Shohel, мы справились с ленивой загрузкой. Мое сомнение в том, как разработать масштабируемое приложение с 20+ разработчиком, может работать с минимальной зависимостью. И как привести всю функцию вместе с определенной конвенцией. Попытка рисовать и диаграмму архитектуры. – Anandh
Нет проблем. Они будут работать только на своем мудрый javascript-файл, например, на контроллер, службу и директиву, вам нужно создать общую службу, фабрику. – Shohel