• Что такое Redux простыми словами?

    jQuery "видит" весь DOM целиком. И манипулирует DOM-ом, доступ к которому предоставляет браузер. Но можно и по-другому.

    Давайте рассмотрим такую архитектуру, в которой все компоненты связаны между собой древовидно. То есть, отдельно взятый компонент может общаться со своими дочерними и со своим родительским. Если нужно, чтобы между собой пообщались два компонента в разных ветках, то в конце концов их общение происходит через общего предка. Такой подход вполне согласуется с древовидной структурой HTML.

    Затем отделим состояние от поведения и представления. Состояние можно описать статической структурой данных, JSON-ом, например. А поведение - это чистая функция, из предыдущего состояния и некоего события (действия) делающая следующее состояние. Представление же "знает", как визуализировать состояние. Можно этот принцип воспроизвести от самых мелких компонент (не имеющих потомков) в нашем дереве и до корня. Тогда весь жизненный цикл приложения можно изобразить как цепочку состояний от некоего начального и до текущего, ведомую событиями (действиями).

    Для того, чтобы это всё отобразить, не обязательно в ходе вычисления следующего состояния (или представления) сразу манипулировать DOM-ом. Можно построить из состояния и его представления фрагмент DOM-а, каким он должен получиться. А потом вычислить diff между этим построенным фрагментом (виртуальным DOM-ом) и реальным браузерным. И этот diff применить к реальному DOMу. Один раз. Получится быстро.

    Насколько мне известно (поправьте, если это не так), Redux заимствован из Elm-а. Elm - это экосистема и функциональный язык, компилируемый в JS, сделанный для того, чтобы фронтэнд можно было разрабатывать удобно, быстро и без runtime-ошибок. По синтаксису - это адаптация Haskell-a. Ключевым элементом Elm-а является как раз вот эта самая архитектура. Советую подробнее почитать в первоисточнике. https://guide.elm-lang.org/architecture/

    Кроме упомянутых особенностей эта архитектура также позволяет выполнять так называемую time-travelling отладку. Поскольку каждое состояние и каждое событие по пути от исходного до текущего можно залогировать и воспроизвести (ведь функция, вычисляющая следующее состояние у нас чистая).

    С точки зрения функционального программирования, при таком подходе текущее состояние является результатом функции leftFold, применённой к исходному состоянию, последовательности событий (действий), приводящих к текущему и функции, умеющей вычислять следующее состояние.
    Ответ написан
    Комментировать
  • Чем отличается процедурное программирование от императивного?

    При императивном подходе можно считать, что в Вашем распоряжении есть исполнитель, который понимает определённый набор команд. Он может копать, может не копать, может сделать ветвление, цикл, присвоение, вызов и т.д.

    Императивному подходу часто противопоставляют декларативный. Вы не говорите, что должен делать исполнитель. Вместо этого описывается (декларируется) желаемый результат. Как правило, декларативный подход является более высокоуровневым. Например, составляя SQL запросы, мы не рассказываем СУБД, как именно получать результат (как правило). Это детали реализации, которые нас не волнуют.

    Сравните, например, два подхода к управлению инфраструктурой:
    • Зайти по SSH на такую-то машину;
    • Установить такой-то пакет;
    • Скопировать конфиг туда-то.

    и
    • Мне нужна машина такая-то,
    • На которой есть такой-то пакет,
    • У которого есть такая-то конфигурация.
    Процедурное программирование - это способ организации императивных программ. Во-первых, это программирование структурное. Условно говоря, у нас нет оператора goto. Есть процедуры. В качестве параметров процедуры получают рычаги для манипуляции данными. В своём коде процедуры "дёргают" за эти рычаги. Они могут читать свои параметры, менять свои параметры, выполнять к ним вызовы. Вы можете столкнуться с процедурным программированием при написании хранимых процедур для PostgreSQL. Из реального мира: отдавая туфли в починку, Вы применяете процедурный подход.

    Для полноты картины тут же нужно упомянуть о чистых функциях. В отличие от процедур, чистая функция не может изменять состояние своих параметров. И не может изменять состояние внешнего мира. Поэтому она чистая. В ходе работы чистая функция формирует некоторую сущность, которую "возвращает" по завершении. В реальном мире в качестве примера чистой функции можно привести консультацию врача. Входной параметр - Ваше состояние. Выходное значение - рекомендации и назначения.
    Ответ написан
    Комментировать
  • Как правильно разбить проект на модули? И как правильно организовать связь между ними?

    Вопрос очень важный и сложный. На разбиение проекта на модули могут влиять и процессы в моделируемом бизнесе, и организационная структура команды разработки (см "Закон Конвея"). И если второе можно (потенциально) изменить по потребностям, то первое нужно как минимум выяснить. Возможности внесения изменений в бизнес-процессы ограничены, как правило, но в любом случае нужно понять фактическое состояние предметной области.

    В последние годы получила развитие методика Event Storming. На эту тему уже есть много видео и даже книжка [наполовину] (https://leanpub.com/introducing_eventstorming). Ключевая идея в том, чтобы выяснить, что должно произойти до того, как мы попадём в то или иное известное состояние. Методика представляет особенный интерес в контексте микросервисов. Предложение oxidmod также имеет к этому непосредственное отношение.

    Но кроме системного уровня, нужно также разбивать на модули отдельные компоненты, чтобы можно было их помещать в голове, тестировать и развивать независимо друг от друга. Здесь Вам поможет Гексагональная архитектура (которая также называется "Порты и адаптеры"). Эта концепция поможет разделить компонент на части, реализующие бизнес-функции и (по отдельности) внешние взаимодействия: с файловой системой, с БД, с HTTP клиентами-сервисами и др.

    На ещё более низком уровне советую освоить 1) отделение чистых функций от эффектов и 2) функциональную композицию - это идеи из функционального программирования. Не знаю, как с ФП в PHP, но тут практикующие программисты PHP могут подсказать.
    Ответ написан
    Комментировать
  • Какие есть хорошие практики автоматизации повтора действий завершившихся с ошибкой?

    Для работы в таких условиях хорошо подходит Модель Акторов. Её важной частью является понятие супервизирования. Дочерний актор - "рабочий" - реализует рискованную логику. Если он упал - супервизор решает, что делать дальше. Среди стандартных паттернов есть, например, ExponentialBackoff: пауза между попытками возрастает до достижения определённой величины (например, 5 минут) или лимита количества попыток.
    Ответ написан
    Комментировать
  • Как быстро освоить angular?

    Подавляющее большинство доступного материала освещает основы Ангуляра. Безусловно, это та матчасть, без которой далеко не уедешь. И я думаю, Вы уже с ней справились.

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

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

    Другого пути нет. Сами фреймворки (и Ангуляр - далеко не самый простой из них) дают общий набор соглашений, причём далеко не полный, и вокабуляр. Однако без архитектуры приложение не оживёт, и вот это-то и есть самое сложное.
    Ответ написан
    1 комментарий
  • XSD синтаксис, можно ли реализовать конструкцию if else?

    Есть группы подстановки. То есть, можно сказать, что валидным является либо такое содержимое, либо этакое. Вот, по-моему, неплохой пример использования групп: stackoverflow.com/questions/39868769/xsd-element-s...

    Но Вы уверены, что стоит для этой задачи использовать XSD? Это же должно быть средством формальной валидации. То есть, если Ваш компонент получил на вход валидный XSD - значит, он умеет такой документ распарсить. А уже тогда можно проводить бизнес-валидацию, проверять инварианты и т.д.
    Ответ написан
    3 комментария
  • Как сохранить свои изменения во взятом Docker-образе для последующего повторного использования?

    Несмотря на возможность сделать docker commit, то, что Вы получите в результате, будет чёрным ящиком, который непонятно каким образом создан. Хорошая практика в данном случае заключается в том, чтобы описать все изменения, которые Вы производите в контейнере, с помощью Dockerfile-а. Этот Dockerfile можно будет сохранить в системе контроля версий, провести его ревью, модифицировать, воспроизвести в сборочном конвеере.

    Да, под капотом на каждую строчку в Dockerfile-е происходит вызов docker commit, но важно то, что в этом случает сохраняется источник этих изменений.

    Не знаю, как точно настраивается FreePBX, но Вам может понадобиться, например, использовать envsubst для применения переменных окружения, с которыми запущен контейнер, к конфигурационным файлам. А может потребоваться сделать стартовый .sh-скрипт, который при запуске произведёт нужные
    конфигурационные действия.

    В случае использования переменных окружения также очень полезно в скрипте запуска проверить, заданы ли они, и если нет - упасть с осмысленным сообщением об ошибке:
    echo MY_ENV_VAR "${MY_ENV_VAR?MY_ENV_VAR is required!}"
    Ответ написан
    Комментировать
  • На чём лучше прокачивать архитектурный навык разработки моделей предметной области и принципов DDD вообще?

    Как упоминают авторы других ответов, очень важно разделять задачу на части со сфокусированными зонами ответственности. Важно держать под контролем их взаимопроникновение, определять, кто от кого должен зависеть, а кто нет. И каким образом всё это можно согласовать с необходимыми характеристиками разрабатываемой системы. Иначе говоря, древний принцип "Разделяй и властвуй" и его IT-интерпретация "Single Responsibility Principle" - наше всё.

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

    Так от чего же должно зависеть DDD-ядро? Должно ли оно зависеть от конкретной реализации БД или ORM? От того, какие таблицы присутствуют в Вашей реляционной СУБД?
    Или от протокола HTTP? Или, допустим, от конкретной файловой системы? Эти вопросы являются скорее риторическими. Поиск ответов на эти вопросы, а также подхода к тестированию DDD-ядра привели к описанию Hexagonal Architecture (известной также под именем Ports And Adapters). Очень советую узнать подробности и поискать, как Вы могли бы сделать такое доступными Вам средствами PHP.

    Пара других наводящих вопросов: должна ли работа с HTTP как-либо быть связана с взаимодействием с БД? Какой из компонентов системы должен знать параметры подключения к БД? Должны ли совпадать жизненные циклы ответа на HTTP-запрос и агрегатов в DDD-ядре? Должен ли HTTP-фреймворк диктовать Вам организацию DDD-ядра? Должен ли ORM-фреймворк диктовать Вам организацию DDD-ядра? А кто всё-таки должен?

    Буду ждать Ваших комментариев.
    Ответ написан
  • Подойдет ли docker для сложного приложения?

    Docker Compose, как писали в комментариях, решает проблему запуска всего этого в определённой конфигурации на одной машине.

    В продакшене у Вас будет несколько машин. MongoDB, вероятно, будет отдельно. Можно использовать Docker Swarm или Kubernetes. На вкус и цвет. Для Сворма конфг очень похож на конфиг для Docker Compose, только значения, специфичные для окружения, будут другими. Kubernetes тоже конфигурируется YAML или JSON описаниями разнообразных сущностей. Если есть Kubernetes-как-сервис - берите, не пожалеете. А можно вообще обойтись конфигурациями SystemD, которые будут запускать нужные контейнеры. Тогда всё это можно будет описать в unit-файлах SystemD и положить в правильные папочки на Линуксе.

    С версионированием всё просто.

    Во-первых, нужно определиться с репозиторием Докер-образов. Можно и свой развернуть из доступных вариантов (и родной Docker Registry, и Atomic Registry, и Nexus, и GitLab - это всё Open Source). А можно воспользоваться сервисами Docker Hub, Google Container Registry, Quay.io или Amazon.

    Во-вторых, после очередного коммита можно с помощью CI-движка собирать новый образ, присваивать ему тег с очередным номером версии, а в лейблы записывать, из какого коммита он собран.

    Дальше достаточно поправить декларативное описание вашего окружения - там фигурируют образы с тегами. И - вот она, новая версия. И новый файл для Docker Compose.

    Резюме: с Докером эту проблему решить гораздо проще, чем как-либо иначе. То есть, можно с таким же успехом упаковать всё это в несколько полновесных виртуалок, но память имеет свойство заканчиваться.
    Ответ написан
    Комментировать
  • Что нужно знать перед изучением angular и react?

    Про Реакт не скажу, но в Ангуляре (если мы о 2-м - 4-м) очень важной зависимостью является RxJS. Это сама по себе очень полезная вещь.
    Более того, я бы посоветовал вместо Ангуляра и Реакта посмотреть на замечательный фреймворк CycleJS, который построен на идее RxJS. У него очень простая, чистая и мощная архитектура. Если её освоить - многое увидится в новом безоблачном свете. Главный минус CycleJS в отсутствии готовых комплектов вроде Material для Ангуляра. Это скорее инструмент, чем готовое решение. Но в обучении это лишь плюс - больше простора для практики.

    Кроме того, полезно освоить концепцию функционального программирования, насколько это возможно в JS. Идею иммутабельных (персистентных) структур данных. Основные функции высшего порядка (вроде map, flatMap, foldLeft/reduce и др). Функциональную композицию и point-free (tacit) стиль. Очень рекомендую посмотреть на библиотеку Ramda. Всё это не является обязательным пререквизитом для Ангуляра и Реакта, но может существенно повлиять на то, как Вы пишете код.

    CycleJS и Ramda - точно помогут в более углублённом изучении JS.
    Angular очень хорошо учить по книге ng-book 2.
    Ответ написан
    Комментировать
  • Как отслеживать состояние внутри Docker контейнера?

    Вам следует создавать Docker-контейнер таким образом, чтобы в нём работал один ключевой процесс (у которого будет PID 0), завершение которого означает завершение работы контейнера. Код выхода этого процесса будет кодом выхода контейнера. Вы сможете увидеть его в выводе `docker ps --all`. Подробнее здесь: each-container-should-have-only-one-concern. Это не означает, что в контейнере должен быть всего один процесс, но должен быть один такой процесс, жизненный цикл которого неразрывно связан с жизненным циклом контейнера.

    Логи этот процесс должен писать в STDOUT и STDERR - тогда Вы их сможете увидеть с помощью `docker logs ` и перенаправить куда надо с помощью драйвера логирования, настроенного в Докер-демоне. Подробнее здесь: View a container's logs
    Ответ написан
    Комментировать