The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:
Я являюсь большим поклонником Amazon Web Services (AWS). Я использую их практически во всех своих проектах. Одним из их самых популярных сервисов является Simple Storage Service (S3). Это хранилище для двоичных объектов (файлов) с уникальными именами, доступное через HTTP или RESTful API.
Использование S3 очень просто. Вы создаете “bucket” с уникальным именем, загружаете свой “объект” в bucket через их веб-интерфейс или через RESTful API, а затем снова скачиваете его (через HTTP или API).
Amazon предлагает Java SDK, который обертывает их RESTful API. Однако, этот SDK совсем не объектно-ориентированный. Он является чисто императивным и процедурным - он просто отражает API.
Например, чтобы скачать существующий объект doc.txt
из bucket test-1
, вам нужно сделать что-то вроде этого:
Как всегда, процедурное программирование имеет свои неизбежные недостатки. Чтобы преодолеть их все, я разработал jcabi-s3, который является небольшим объектно-ориентированным адаптером для Amazon SDK. Вот как можно выполнить ту же задачу чтения объекта с помощью jcabi-s3:
Почему этот подход лучше? Во-первых, есть несколько явных преимуществ.
S3-объект получает свое представление в Java. Это не набор процедур, которые вызываются для получения его свойств (как с AWS SDK). Вместо этого это Java-объект с определенным поведением. Я назвал их “океты” (аналогично “ведрам”), чтобы избежать конфликтов с java.lang.Object
.
Окет
- это интерфейс, который предоставляет поведение реального объекта AWS S3: чтение, запись, проверка существования. Существует также удобный декоратор Окет.Text
, который упрощает работу с двоичными объектами:
Теперь вы можете передать объект в другой класс, вместо того чтобы предоставлять ему ваши учетные данные AWS, имя ведра и имя объекта. Вы просто передаете Java-объект, который инкапсулирует все детали взаимодействия с AWS.
Поскольку jcabi-s3 представляет все сущности в виде интерфейсов, их легко можно расширить с помощью инкапсуляции (шаблон Декоратор).
Например, вы хотите, чтобы ваш код повторял операции чтения объектов S3 несколько раз перед тем, как отказаться и выбросить исключение IOException
(кстати, это очень хорошая практика при работе с веб-сервисами). Таким образом, вы хотите, чтобы все операции чтения S3 повторялись несколько раз, если первые попытки не удалось.
Вы определяете новый класс-декоратор, скажем, RetryingOcket
, который инкапсулирует исходный Ocket
:
Теперь, везде, где ожидается Ocket
, вы отправляете экземпляр RetryingOcket
, который обертывает ваш исходный объект.
Метод foo.process()
не заметит разницы, так как он ожидает тот же интерфейс Ocket
.
Кстати, эта функциональность повторной попытки реализована изначально в jcabi-s3 в пакете com.jcabi.s3.retry
.
Снова, из-за того, что все сущности в jcabi-s3 являются интерфейсами, их очень легко мокировать. Например, ваш класс ожидает объект S3, считывает его данные и вычисляет хэш MD5 (я использую DigestUtils
из commons-codec).
Вот как будет выглядеть простой модульный тест (попробуйте создать модульный тест для класса с использованием AWS SDK, и вы увидите разницу):
Я использую JUnit и Mockito в этом тесте.
Все классы в jcabi-s3 помечены аннотацией @Immutable
и являются полностью неизменяемыми.
Библиотека поставляется в виде зависимости JAR в Maven Central (получите ее последние версии в Maven Central).
Как всегда, ваши комментарии и критика приветствуются в виде GitHub issues.
Translated by ChatGPT gpt-3.5-turbo/42 on 2023-11-22 at 09:38