• Время кеширование запросов влияет на бизнес логики. Что делать?

    На мой взгляд, проблема не в параметрах запроса, а именно в архитектуре. Как Вы сами справедливо отметили, вопросы кеширования не должны проникать в бизнес-логику.
  • XSD синтаксис, можно ли реализовать конструкцию if else?

    Необходимо ещё уточнить, обсуждаем ли мы ситуацию в контексте xsd 1.0 или в контексте 1.1. Каким инструментом/библиотекой Вы пользуетесь?
  • Как вы организуете свою работу?

    А как же Докер? Сам Докер-демон можно запускать и локально, и на сервере, если локальных мощностей не хватает. И тестить можно сколько угодно.
  • На чём лучше прокачивать архитектурный навык разработки моделей предметной области и принципов DDD вообще?

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

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

    Хобби заслуживает исключительного уважения. Относительно идеи бизнеса изложу свой взгляд. У IT-бизнеса есть редкое качество: он потенциально масштабируем. Это означает, что существуют такие бизнес-идеи, которые при малых затратах человекочасов способны найти миллионы потребителей. Именно такие идеи интересны в первую очередь. Я здесь имею ввиду продуктовую модель. Понятно, что если мы работаем на заказ - то решаем именно эту самую заказанную задачу. Но продукт ориентируется на большое количество потребителей. Собственно, у IT есть два способа заработать много денег: или очень крупный проект, или очень масштабный продукт. Первое - это очень специфическая ниша, в которую кто попало не имеет доступа. Второе - сфера деятельности стартапов. Рискованно, но реально и интересно. Хорошо, не будем говорить "заработать много денег". Скажем политкорректнее: "возыметь большое влияние и резонанс".

    Ещё одно преимущество продуктового подхода перед проектным заключается в том, что все члены продуктовой команды могут иметь гораздо лучшее и более перспективное видение продукта - соответственно, лучшую мотивированность и креативность. Это непосредственно сказывается на работоспособности людей и качестве результата.

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

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

    А с архитектурой нужно экспериментировать. Каждый новый проект будет приносить открытия, если их искать. Если есть стремление делать чистую и простую архитектуру - то постепенно это будет получаться. Заготовку хорошей архитектуры сделать едва ли получится (как и заготовку хорошего дворца, в случае с архитектурой зданий) - это скорее возможность понять, как все изученные понятия вместе работают. Понять, между чем и чем делается выбор; что приносится в жертву, а что выигрывается.

    Вот, кстати, насчёт анемичных моделей мне не совсем понятно. То есть, понятно, что это не ООП-шно. Ну а если я использую не [только] ООП, а функциональный подход? Например, замечательные модели можно строить на F#, на Scala, на Elixir. В последнем случае об объектах вообще не идёт речи: у нас есть именно что структуры данных и функции над ними. А функции открывают массу возможностей, включая функциональную композицию, простоту тестирования, отладки и спецификации. В общем, для меня достоинства богатых доменных моделей являются очень неочевидными. Так что, советую более функциональный подход. Некая структура данных моделирует состояние некоторой сущности. Над этим состоянием можно произвести какое-то чисто логическое действие (функцию без побочных эффектов) и получить новое состояние. С этим новым состоянием можно сделать что угодно: передать кому-то, сохранить в БД, залогировать... И этот вовсе не процедурное программирование с так нелюбимыми Мартином Фаулером транзакционными скриптами. Нет, это отделение чистой логики от эффектов - следующий уровень реализации Single Responsibility Principle. Есть хорошая книжка: Functional And Reactive Domain Modelling. Правда, она достаточно серьёзно опирается на Scala, это проблема. Но какие-то общие принципы вполне можно оттуда почерпнуть. Совсем недавно вышла также книжка, где за основу взяты Elixir и Phoenix: Functional Web Development with Elixir, OTP, and P.... Насчёт PHP не знаю. Возможно, стоит поискать - тема очень уж хороша. Ещё, думаю, отдельную книжку стоило бы посвятить Гексагональной архитектуре (она идеально сочетается с DDD), но такой пока никто не написал.

    А что Вы имеете ввиду под условиями умирающих запросов?

    Золотая середина - это очень ускользающая концепция. Если масштаб системы известен заранее - то выбор будет между решением, достаточным для бизнеса и решением, несущим новый опыт в рамках отведённого времени на него. Если масштаб меняется со временем - будет меняться и золотая середина. Если сложность системы, развитость кода меняется - это тоже окажет своё влияние. Или если меняется доступное для обучения время. Но зато можно каждый раз делать выбор с открытыми глазами.
  • На чём лучше прокачивать архитектурный навык разработки моделей предметной области и принципов DDD вообще?

    Употребляя слово "знает", я имею ввиду зависимости в коде. То есть, в php получается, что всё начинается с входящего http-запроса. Это означает, что где-то при обработке запроса задействуется ServiceLocator, который, вероятно, возвращает объект для работы с БД. Получается, что обработчик http-запроса "знает" о существовании БД. Он же, вероятно, создаёт экземпляр модели и передаёт кому-то свои "знания" о БД, чтобы с моделью можно было что-то сделать.

    Вот и получается, что первую скрипку играет обработчик http-запроса, который по совместительству является точкой входа в приложение. А все остальные адаптируются под этот обработчик. Или фреймворк. Что противоречит логике и смыслу DDD.

    Теперь про часть модели. Не помню точно источник цитаты, но где-то приведены слова Эрика Эванса о том, что если бы он писал эту голубую книгу сейчас, то начал бы с Ограниченных контекстов. Потому что именно это является самым важным в DDD: разбиение задачи на набор ограниченных контекстов, которые находятся между собой в определённых отношениях. И он описал виды этих отношений. Кроме этого, внутри самих контекстов разбиение на агрегаты устанавливает границы транзакций. Об этом достаточно подробно писал Vaughn Vernon в книге Implementing Domain-Driven Design.

    С REST проблема в том, что в данном случае предметная область не вписывается в ресурсную модель. Ведь именно поэтому мы и используем DDD. Наверно, из фронтэнда формируются запросы к агрегатам. Но агрегаты в объектном виде не являются ресурсами. Они сами по себе обладают сложной внутренней логикой. Если переносить эту логику на фронтэнд, то мы получим толстого клиента, двухзвенную архитектуру. Если с таким подходом всё сработает - отлично, используйте Firebase. Но с DDD нужно поступать иначе. И ресурсная модель тут оказывается очень полезной.

    Я предлагаю применить CQRS - Command-Query Responsibility Segregation. При таком подходе фронтэнд либо направляет агрегатам команды, которые и являются ресурсами, либо запрашивает представление некоторой модели для чтения.

    Вот какие у нас образуются компоненты и роли:
    • Команда - ресурс, иммутабельная структура данных, содержащая всё необходимое для того, чтобы агрегат мог решить, что с ней нужно сделать.
    • Агрегат - хранит состояние части предметной области; принимает команды, в результате чего может изменить состояние; при изменении состояния издаёт оповещение, которое могут использовать другие компоненты.
    • Контроллер модели для чтения - подписывается на оповещения от интересующих его типов агрегатов (возможно, в разных контекстах) и формирует (или обновляет) денормализованную модель для чтения, которую складывает в key-value или документную db (или в blob, на худой конец); при обновлении модели издаёт оповещение для заинтересованных компонентов.
    • Модель для чтения - ресурс, документ; как правило JSON,
      запрашиваемый фронтэндом.
    • Запрос к контроллеру коллекций - ресурс, иммутабельная структура данных, предусматривающая каноникализацию и вычисление хеша; описывает параметры поиска, фильтрации и сортировки определённой коллекции.
    • Контроллер коллекций - принимает запросы к коллекции (аналогично тому, как агрегаты принимают команды), реализует логику поиска, фильтрации и сортировки моделей для чтения; в результате работы создаёт новую модель для чтения - коллекцию.
    • Коллекция - ресурс, поддерживающий постраничное листание. Задача коллекции - дать краткое описание и гиперссылки на модели для чтения входящих в неё элементов


    Ресурсы, как правило, представлены иммутабельными структурами данных и содержат логику максимум для авторизации.

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

    Также несложно добавить сюда Event Sourcing там, где он нужен. Для этого достаточно состояние агрегатов хранить в БД в виде последовательности событий, описывающих изменение их состояния. Тогда контроллеры моделей для чтения должны уметь делать foldLeft этих последовательностей. Очень удобно в том случае, если необходимо хранить не только текущее состояние модели предметной области, но и историю изменений.

    Фронтэнд теперь может спокойно работать в REST-стиле. На бэкэнде дополнительно потребуется логика для формирования гиперссылок. Получается так:
    1. Фронтэнд формирует запрос к контроллеру коллекции, выполняет POST.
    2. Контроллер коллекции собирает коллекцию, отвечает Created с гиперссылкой на коллекцию.
    3. Фронтэнд идёт по этой ссылке к ресурсу коллекции (GET), получает от ресурса коллекции первую страницу и вместе с ней ссылки на другие страницы.
    4. По ссылке из коллекции запрашивает (GET) модель для чтения, в которой есть ссылки на необходимые агрегаты.
    5. Фронтэнд формирует команду и обращается с ней к нужному агрегату (POST), получает в ответ Created и ссылку на созданную команду. Идёт по ссылке и получает описание команды вместе со ссылками на модели для чтения, которые были созданы или обновлены в результате выполнения команды (или сообщение об ошибке).
    6. Фронтэнд запрашивает (GET) нужную модель для чтения и показывает её пользователю.

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

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

    По моему собственному опыту могу сказать, что очень удобно (даже ОЧЕНЬ удобно) моделировать серверную логику с помощью модели акторов. В PHP такой, по-моему, нету. Модель акторов реализована нативно в Erlang/Elixir, а также в виде библиотек на .Net, JVM и других языках и платформах. С её помощью получается физически разделить http-сервер, адаптеры к хранилищам данных, бизнес-компоненты. Тогда они живут со своими собственными жизненными циклами и обмениваются друг с другом асинхронными сообщениями. Например, представление агрегата может жить в памяти сколько-то секунд после выполнения команды. Тогда, если следующая команда укладывается в отведённый таймаут, агрегат не нужно будет заново вытаскивать из хранилища. Кроме того, у агрегатов, контроллеров моделей для чтения и контроллеров коллекций жизненные циклы не совпадают.

    Но модель акторов - это уже совсем другая история, сильно выходящая за рамки исходного вопроса.
  • Как моделировать REST ресурсы и доменные объекты?

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

    Мне кажется, тут происходит некоторая путаница понятий. Предметную область не нужно передавать с сервера на клиент. В разные моменты времени передаётся лишь некоторое её представление. Кроме того, не покидает ощущение, что где-то в Вашей формулировке закопан CRUD. Но если мы говорим о Domain-Driven Design, то, как правило, решаем задачу, которая в CRUD не вписывается.
  • Время кеширование запросов влияет на бизнес логики. Что делать?

    Если Вы готовы рассматривать другие варианты, могу предложить архитектурно иное решение с применением CQRS/ES, EDA и REST.