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

    Весь вопрос звучит как какой-то оверинжиниринг.
    0. Без диаграмм вообще поток мыслей сложно понять.
    1. Фасад - это не способ легализовать божественный класс.
    2. Циклические зависимости - это не всегда смертельно плохо, но всегда очень подозрительно.
    3. Не нужно накидывать все паттерны, какие ты знаешь, если только что прочитал какую-то умную книжку или статью. Иногда лучше всё-таки сделать по принципу KISS и YAGNI.

    Или мне нужно создать объект PriceConvert и вызвать нужный метод?

    Зачем на каждую мелкую операцию делать отдельный класс и создавать постоянно новые объекты?

    Просто с одной стороны фасад Payments лежит ниже чем эти классы - это просто точка доступа для контроллеров итд.

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

    и у них внутренние связи налажены через parent
    .
    Что это вообще значит?

    Payments::priceConvert

    Почему вообще платежи отвечают за конвертацию курсов валют? Или что делает priceConvert?
    Ответ написан
    8 комментариев
  • Чем отличается папка public от shared/assets/images?

    Попробую предположить, что в assets лежит то, что используется приложением (всякие иконки, иллюстрации итд), а в public - то что непосредственно приложением не используется, но необходимо для сайта.
    Ответ написан
    1 комментарий
  • Можно ли в одном микросервисе использовать Postgres и MongoDB?

    Можно, разрешаю, но выглядит как-то странно.
    Я бы задумался над возможностью переноса всех данных либо в монгу, либо в постгрес, чтобы в будущем не возникало проблем с консистентностью данных.
    Ответ написан
  • Какой проект можно сделать на базе rpc?

    Ну давай начнём с самого простого: пусть клиент передаёт два числа, а сервер отвечает суммой этих чисел
    Ответ написан
  • Есть ли такая архитектура?

    то уже нет смысла ни в UnitOfWork, ни в Repository. То есть можно избавиться от Infrastructure слоя, чтобы схема была уже такая: UI, Application, Domain.

    Infrastructure слой нужен не для того чтобы заменять базу в будущем, а чтобы работа с базой не захламляла домен.
    Да и "никогда переходить не планируется" - это достаточно громкое заявление.

    Просто в случае с UnitOfWork и Repository накладывают только лишнюю нагрузку, потому что это и так реализовано в EntityFramework.

    Тогда будет усложнено тестирование, так как ты не сможешь замокать EF.
    Лучше всю работу по построению запроса тоже вынести куда-то в инфраструктурный слой - тогда и UoW и "Repository" не придётся тащить в домен.
    Ответ написан
    Комментировать
  • Вопрос с собеседования на Java Бекенд. Как гарантировать согласованность операций?

    Я не из МТС банка, но у нас в собесе тоже есть похожий вопрос, но я бы не назвал его простым, так как там дальше ещё много дополнительных вопросов и обсуждений можно невертеть.

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

    Самый простой и часто используемый вариант - Outbox.

    Смысл в том, что мы должны в нашей основной базе завести таблицу, в которой будет записано, что нам нужно отправить запрос в тот сервис и с какими параметрами. (Например отправить письмо по электронной почте)

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

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

    Переносить взаимодействие со сторонним сервисом в Outbox также имеет смысл из-за того что ты не можешь гарантировать его доступность и задержки - если будешь работат с ним при обработке запроса от клиента по API, то можешь просто упасть по тайм-аут.

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

    66ab5b548e5a9142225375.png

    Благодаря тому что мы записываем основные бизнес-данные и намерение сделать запрос в сторонний сервис в одной транзакции - мы гарантируем, что мы не будем отправлять запрос, если данные не записались и наоборот - если данные записались, то мы гарантируем, что попытаемся рано или поздно отправить запрос.
    Ответ написан
    3 комментария
  • Как правильно создается и поддерживается архитектура для микро сервисов?

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

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

    Но как быть с задачами, когда она касается клиентского сервиса и одного из серверов?

    Это две разные задачи: одна на сервер и одна на клиент.
    API должен быть спроектирован так, чтобы сервер был обратно совместим с клиентом.
    Если всё-таки клиент и сервер должны будут обновляться одновременно, то тогда нужно координировать релизы - опять же к веткам в репозитории никакого отношения не имеет.
    Ответ написан
    Комментировать
  • На чём писать клиентское приложение с GUI?

    Можно посмотреть в сторону PWA и кэшировать данные в local storage или на диск.
    Ответ написан
    Комментировать
  • Как должна работать интеграция VK ID в SPA в описанном случае?


    Что должен возвращать mysite.com/redirect пользователю?

    Тот же самый токен, который бы твой сайт вернул при обычной аутентификации и отправить пользователя дальше
    Ответ написан
    3 комментария
  • Как организовать БД, если данные нужно отправлять по разным АПИ, в запросах которых поля отличаются?

    Если не упарываться в NoSQL, то можно классическим реляционным подходом - EAV-паттерн применить.
    Если постгрес, то можно его в документ-ориентированную базу превратить, благодаря jsonb полям.

    Я бы ввёл две таблицы:
    1. "Описание услуги" - с перечислением всех полей, которые должны быть указаны в заявке. (чтобы можно было сформировать форму)
    2. "Заявка" - там все специфичные поля записываются в jsonb-колонку.

    GraphQL позволит гибко настраивать payload для внешних API

    Мне кажется, что в этом случае GraphQL не очень подходит, так как у контрагентов может быть свой интерфейс взаимодействия => всё равно в коде нужно будет реализовать коннектор для каждого.
    Ответ написан
    1 комментарий
  • Какая архитектура бекенда для временной информации(капча и пр.)?

    Тут напрашивается Redis.
    1. Ничего страшного не произойдёт, если разок при вводе капчи пользователя попросят ввести её ещё раз, если на стороне твоего Бэка что-то потеряется.

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

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


    Чтобы данный сервис был доступен в окружении Lib.Controls, я реализую в этой библиотеке статический класс:

    Фатальная ошибка.


    Является ли такая архитектура единственно возможной или у нее есть достойные альтернативы?

    Раз у тебя уже есть DI, то следующий шаг прямо напрашивается. Создавать формы тоже при помощи DI и прокидывать все такие зависимости через конструктор.
    Ответ написан
    2 комментария
  • GRPC или RabbitMQ что лучше использовать для взаимодействия между API Gateway и микросервисами?

    1. Зачем вообще нужны усложнения, почему в рамках ваших сервисов не использовать rest api (обычный голый http с json-ами)?
    2. grpc vs rabbitmq - это больше вопрос про синхронное vs асинхронное взаимодействие.
    В зависимости от конкретного случая может быть лучше одно, а может быть лучше другое.
    Как правило при использовании api gateway имеет место синхронное взаимодействие, тк ожидается, что сервер ответит на http-запрос в течение пары секунд (как правило меньше секунды).

    При желании, можно поверх rabbitmq устроить rpc, но там всё равно будет более высокая нагрузка на железо, чем если бы напрямую происходил вызов.
    Ответ написан
    2 комментария
  • Как лучше возвращать ошибку API?

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

    Но если хочется облегчить жизнь фронту (и усложнить бэку), язык на сайте только русский, и API будет пользоваться только сайтом, то можно на бэке формировать сообщение об ошибке.
    Ответ написан
    Комментировать
  • Где лучше всего хранить sms коды?

    Тут нет "более правильного" варианта.
    Программная инженерия - это всегда про компромисс.

    Я бы выбрал вариант с уже имеющейся базой данных, тк это:
    1. Уже проверенное решение
    2. Это решение очень простое и понятное
    3. Оно не подразумевает усложнение инфраструктуры
    4. Оно точно устроит тебя по производительности.
    Ответ написан
    Комментировать
  • Что лучше выбрать для взаимодействия в микросервисной архитектуре? MessageBroker или REST?

    Зависит от того что именно за данные (для какой цели) будут передаваться и между кем и кем.
    Rest как и любой другой синхронный метод взаимодействия несёт плюсы:
    + Сравнительно быстрая реакция на запрос и ответ. (как правило от запроса до получения ответа менее секунды)
    + Очень прост в использовании, нет никаких проблем с поддержкой на клиенте
    + Очень простая инфраструктура (в минимальном варианте она не нужна вообще)
    + Всё хорошо изучено. Та же аутентификация и авторизация очень легко реализуется в рамках http.
    + Достаточно легко разрабатывать и тестировать
    + Есть grpc и openapi - нет никакой проблемы с документированием такого API.
    + В http запрос с каким-нибудь multipart form data может спокойно быть размером в десятки мегабайт, а может и больше - полезно при загрузке файлов.
    И минусы:
    - Не понятно что делать, в случае недоступности ответной стороны
    - При неправильной реализации клиента (политики ретраев) - можно легко заддосить сервер

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

    Но есть и минусы:
    - Инфраструктура обычно сложнее
    - Достаточно большие задержки
    - Использовать можно будет только у себя внутри - внешнему клиенту (браузер, мобильное приложение, публичный API) такое дать не получится.
    - Сложнее разграничивать в правах.
    - Сложно разрабатывать и тестировать. На примере той же кафки - подключиться к топику и записать в него что-то через гуй - это отдельный челендж.
    - Запросы должны быть небольшими (сотни кб)
    Ответ написан
    2 комментария
  • Как реализовать чексуммы для сетевого протокола уровня приложения?

    При использовании TCP стека (Ethernet, IP, TCP) не гарантируется сохранение целостности.

    Гарантируется.
    Ответ написан
    7 комментариев
  • Что такое компонент? Что такое модуль?

    Существую 2 термина, компонент и модуль. Но что они обозначают?

    Зависит от контекста.
    Начнём с компонента, компонент, как мне представляется...

    Вот это "как мне представляется" будет зависеть от контекста => дальше можно не читать.

    А судя по схеме зависимостей компонентов (из раздела "принцип ацикличности зависимостей"), автор объединяет в компонент Controllers все контроллеры, в Entities все сущности:

    Если обратишь внимание на текст, то там написано "типичная диаграмма компонентов", а не "эталонная архитектура".

    Судя по всему у автора слой === компонент?

    Видимо. А есть Jimmy Bogart, который делает наоборот: https://www.youtube.com/watch?v=5kOzZz2vj2o

    PS: википедия
    Модуль (программирование) — функционально законченный фрагмент программы, оформленный в виде отдельного файла с исходным кодом или поименованной непрерывной её части.

    Модуль - это какая-то часть программы, которой дали имя. (например функция или класс)
    Видимо тут Модуль = Единица (Unit)

    (Компонент) В программировании — множество классов и языковых конструкций, объединенных по общему признаку, предназначенного для повторного использования и развёртывания. В большинстве языков программирования нет языковых конструкций прямо отражающих понятие компонента. Компоненты реализуются с помощью стандартных конструкций, таких как классы

    Компонент - какая-то самодостаточная совокупность из модулей, которая может использоваться повторно.

    Но в других контекстах это может быть иначе.
    Ответ написан
    Комментировать
  • На что опереться при проектировании API (паттерны, концепции)?


    Вот пришел ко мне товарищ и говорит, мол а почему я не могу в API сделать метод DELETE и в него передавать и тип объекта, и его id.

    Может, да только это не по ресту будет.
    А если по ресту - тип и id и так передаются в URL.
    Но рест - это не стандарт и не Верховная истина,
    Если мешает иерархия, то никто не запрещает делать один ресурс доступным по нескольким разным путям.
    и при необходимости его можно нарушать - так появился jsonrpc например
    Ответ написан
    Комментировать