В своей предыдущей статье я писал о принципах ООП для приложения PHP / Laravel. Немного проще разработать внутреннее приложение PHP, потому что в этом вам помогут такие фреймворки, как Laravel. Однако для внешнего интерфейса JavaScript это гораздо более сложная задача.

Важнейшие принципы ООП

Наиболее важными принципами ООП являются SoC - разделение проблем и DRY - не повторяйтесь. Если вы будете следовать этим двум правилам, ваша жизнь программирования станет намного проще, а ваш код красивее и легче будет расширяться.

Вопрос в том, как применить эти принципы к клиентскому приложению? Мне нравится работать с VueJs, поэтому я буду использовать его в качестве примеров.

TypeScript и его сильные стороны

Если вам нравится VueJs, вы, вероятно, привыкли писать код на JavaScript. Однако, как я покажу далее, полезно выделить некоторый код вне компонентов Vue. Вопрос в том, как написать этот «внешний» код.

Я начал с ванильного JS, но быстро понял, что хочу что-то более безопасное. Я переписал код на TypeScript, используя типы, классы и другие функции TS. С тех пор я применяю тот же подход. Использование типов поможет вам создать более безопасный код и отловить все возможные ошибки во время компиляции.

Я настоятельно рекомендую TS для любого кода за пределами Vue. На самом деле Vue тоже может использовать TS, но поскольку я стараюсь делать функции компонентов Vue короткими, JS работает нормально.

Интерфейсное приложение, созданное с использованием компонентов TypeScript и Vue

Проверьте файлы проекта в репозитории git.

Webpack (в настоящее время версия 4) позволяет создавать пакеты и выполнять отложенную загрузку всех компонентов только тогда, когда они необходимы. Нам не нужно включать много файлов. Только runtime.js, vendors.js и основной файл записи. Я обычно разбиваю свой код на две основные записи. Один для передней - это все функции, необходимые для общедоступных веб-частей. Другой для задней части - это все, что нужно после входа пользователя в систему.

Предположим, что основным входным файлом будет frontApps.ts.

Входной файл - frontApps.ts

Это основной файл приложения, который импортируется в ваш html-код. Выглядит это так:

  1. bootstrap.js создает глобальные объекты, такие как JQuery, и импортирует объявление Vue в глобальное пространство.
  2. Затем создается контейнер IoC. Это будет описано позже в коде. По сути, контейнер предоставляет вам все классы и обрабатывает зависимости. Функциональность контейнера аналогична тому, что использует Laravel.
  3. Мы создаем класс Application, основной класс всего приложения. Однако, поскольку экземпляр Application внедряется в модули Vue, вы можете создать несколько экземпляров и при необходимости разделить проект на несколько частей. Приложению требуется Контейнер в качестве зависимости.
  4. FrontAppServiceProvider похож на поставщика услуг приложений Laravel. Он регистрирует все классы, которые могут понадобиться вашему приложению. Вы можете создать столько поставщиков услуг, сколько необходимо для разделения кода.
  5. vueLoader - последний вызов в этом файле, обрабатывающий все независимые приложения Vue.

Контейнер для инверсии управления (IoC)

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

Контейнер позволяет связать имя с новым классом или синглтоном. После регистрации класса вы можете разрешить его где угодно, используя:

let myClass = app.resolve('MyClass')

Если MyClass был зарегистрирован как одноэлементный, resolve () всегда будет возвращать один и тот же экземпляр. Вы можете зарегистрировать новый класс в любом месте кода, но в этом случае IoC будет нарушен. Лучшее место для записи на занятия - это поставщик услуг.

Класс можно зарегистрировать двумя способами - как синглтон или как новый класс. Каждая из этих двух может быть простой привязкой или закрытием. Замыкание - это анонимная функция, которая знает, как создать желаемый класс. Давайте рассмотрим несколько примеров:

Класс BlogBroker имеет одну зависимость BrokerCore. BlogBroker ожидает, что экземпляр BrokerCore будет передан его конструктору. Контейнер будет рекурсивно искать все зависимости и создавать их за вас.

Загрузка модулей Vue

Если вы не создаете приложение SPA, у вас может быть несколько экземпляров Vue. Если вы создаете новый экземпляр Vue, а элемент не найден, Vue кричит вам, что компонент отсутствует. Поэтому лучше импортировать модуль только в том случае, если он вам действительно нужен. Webpack выполнит всю загрузку пакета за вас.

if(document.getElementById(“articleEditorModule”)){
   import(‘../Blog/ArticleEditor/ArticleEditor.Module.js’);
}

В этом случае модуль ArticleEditor будет загружен, только если присутствует элемент с идентификатором articleEditorModule. Модуль - это просто новый экземпляр Vue. Это место для включения приложения путем вызова appInstance (). Он будет внедрен во все дочерние компоненты.

import {appInstance} from '../../../App core/Application';
new Vue({
  el: '#articleEditorModule',
 provide : {
    app : appInstance(),
 },
…

Разрешение классов в компонентах Vue

Разрешить классы в компоненте Vue просто. Поскольку экземпляр Application передается модулю, его можно внедрить в любой дочерний компонент следующим образом:

export default {
 inject : ['app'],
 props : {
…

Затем вызовите функцию resolve (‘ClassName’), чтобы создать экземпляр любого зарегистрированного класса.

this.serverExceptions = this.app.resolve('ServerExceptions');
this.exceptionHandler = this.app.resolve('ExceptionHandler');

Что дальше?

Компоненты Vue, как правило, делают слишком много вещей. Например, если у вас есть несколько компонентов, подключенных к API, возможно, все они вызывают Axios для связи с сервером. Это очень непрактично, потому что каждый компонент имеет копию одной и той же функции. Принцип DRY полностью нарушен. Вдобавок ко всему, если потребуются какие-либо манипуляции с данными, вам придется решать одну и ту же проблему снова и снова.

В части 2 этой серии мы покажем, как отделить взаимодействие API от компонентов Vue и как это упрощает кодирование. Продолжайте здесь.