Untitled

 avatar
unknown
plain_text
5 months ago
5.4 kB
9
Indexable
Добрый день.
Как договорились с HR мы договорились что я попробую решить задачу только на уровне обсуждения реализации/архитектуры.
Я взял на себя смелось показать свои рассуждения чуть подробней.
вот тот минимальный подход чтобы это работало легко маштабировалось и изменялось.

src/
- Command/
  - ImportCurrencyRatesCommand.php    // Вызывает ImporterInterface через MiddlewareImporter
- Controller/
  - CurrencyConversionController.php  // Вызывает ConverterService для обработки конвертации
- Entity/
  - ExchangeRate.php                  // Сущность данных, может использовать Serializer для отправки в REST и аннотацией доктрины.
- Repository/
  - ExchangeRateRepository.php        // Извлечение и сохранение курсов валют
- Service/
  - ConverterService.php              // Сервис для расчета конвертации
  - Importer/
    - ImporterInterface.php           // Интерфейс для всех импортёров
    - ECB/
      - ECBImporterService.php        // Логика импорта данных с ECB
      - Parser.php                    // Парсит XML-файл и возвращает ExchangeRate
    - CBR/
      - Parser.php                    // Парсит XML-файл и возвращает ExchangeRate
      - CBRImporterService.php        // Логика импорта данных с CBR
    - ExchangeRate.php                // Объект значений (Value Object) для обменных курсов
    - MiddlewareImporter.php          // Определяет, какой сервис загружать, используя массив сервисов



Но дальше можно лучше.
Следующие пункты которым я придерживаюсь в текущем проекте это
- разделение на слои application, infrastructure, domain.
- выделение еще 1 слоя Bridge. где всё что завязано на framework, и ACL слой тамже.
- аннотации для доктрины вынес бы не в Entity а в xml чтобы разделить domain и infrastructure
- Добавил бы сущность ресурсов которые возморащаются для RESTApi.



src/
- Bridge/
  - Symfony/
    - Command/
      - ImportCurrencyRatesCommand.php    // Вызывает Importer через MiddlewareImporter
    - Controller/
      - CurrencyConversionController.php  // Использует ConverterService
- Application/
  - Input/
    - CurrencyConversionRequest.php     // Объект для валидации данных от REST-запроса (DTO, или так же это могут быть просто формы)
  - Resources/
    - CurrencyConversionResponse.php    // Объект-ресурс для ответа REST API

- Domain/
  - Entity/
    - ExchangeRate.php                  // Сущность курсов валют
  - Service/
    - ConverterService.php              // Логика для конвертации валют
  - ValueObject/
    - ExchangeRate.php                  // Объект значений курса валют
  - Repository/
    - ExchangeRateRepositoryInterface.php // Интерфейс для репозиториев курсов валют

- Infrastructure/
  - Repository/
    - ORMExchangeRateRepository.php      // Реализация репозитория через Doctrine
  - Service/
    - Importer/
      - ImporterInterface.php           // Интерфейс для импортёров
      - MiddlewareImporter.php          // Решает, какой импортёр использовать
      - ECB/
        - ECBImporterService.php        // Импорт данных с ECB
        - Parser.php                    // Парсер данных ECB
      - CBR/
        - CBRImporterService.php        // Импорт данных с CBR
        - Parser.php                    // Парсер данных CBR


Так же есть хороший вопрос оптимизации запроса.
Например если при каждом платеже мы делаем запрос курса валюты, то это не оптимально.
Я делал похожий сервис при сборе данных с крипто биржи.
Помимо сохранения курса валюты в базу, эти данные хранились в redis, и при пересчете доставал из redis.
Можно реализовать доставая CacheRateReader в ConverterService и дальше делая расчеты.
Или делать этот redis storage напрямую доступным для чтения другим сервисам.
Всё в зависимости от требований к производительности и сложности сервиса.

Буду рад обсудить детали и ответить на вопросы.
Editor is loading...
Leave a Comment