Object-Oriented Java Adapter of Amazon S3 SDK

The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:

我是亚马逊网络服务(AWS)的忠实粉丝。我在几乎所有的项目中都在使用它们。他们最受欢迎的服务之一是简单存储服务(S3)。它是一个用于存储二进制对象(文件)并具有唯一名称的存储服务,可以通过HTTP或RESTful API进行访问。

使用S3非常简单。您可以通过他们的网络界面或RESTful API创建一个具有唯一名称的“存储桶”,将您的“对象”上传到存储桶中,然后再次通过HTTP或API将其下载。

亚马逊提供了Java SDK来封装他们的RESTful API。然而,这个SDK完全不是面向对象的。它纯粹是命令式和过程式的,只是API的镜像。

例如,要从存储桶“test-1”下载一个已经存在的对象“doc.txt”,您需要像这样做:

和往常一样,过程式编程有其不可避免的缺点。为了克服这些缺点,我设计了jcabi-s3,它是一个用于Amazon SDK的小型面向对象适配器。下面是使用jcabi-s3完成相同对象读取任务的方法:

为什么这种方法更好呢?嗯,有一些明显的优势。

S3对象在Java中有其代表。它不是一系列按顺序调用以获取其属性的过程(与AWS SDK不同)。相反,它是一个具有特定行为的Java对象。我称之为“ockets”(类似于“buckets”),以避免与java.lang.Object发生冲突。

Ocket是一个接口,展示了真实的AWS S3对象的行为:读取、写入、检查存在性。还有一个方便的装饰器Ocket.Text,简化了与二进制对象的处理。

现在,您可以将一个对象传递给另一个类,而不是提供您的AWS凭证、存储桶名称和对象名称。您只需传递一个Java对象,该对象封装了所有AWS交互细节。

由于 jcabi-s3 将所有实体都公开为接口,因此可以通过封装(装饰者模式)轻松扩展它们。

例如,您希望在放弃并抛出 IOException 之前尝试几次 S3 对象读取操作(顺便说一句,这是在使用 Web 服务时的一种很好的做法)。因此,如果首次尝试失败,您希望所有的 S3 读取操作都重新执行几次。

您可以定义一个新的装饰者类,比如 RetryingOcket,它封装了一个原始的 Ocket

现在,无论何处需要 Ocket 的地方,您都需要发送一个包装原始对象的 RetryingOcket 实例。

方法foo.process()不会看到任何差异,因为它期望的是相同的Ocket接口。

顺便说一下,这个重试功能在jcabi-s3中已经实现了,位于com.jcabi.s3.retry包中。

由于jcabi-s3中的所有实体都是接口,它们非常容易进行模拟。例如,您的类期望一个S3对象,读取其数据并计算MD5哈希(我正在使用commons-codec中的DigestUtils):

以下是一个单元测试的简单示例(尝试使用 AWS SDK 为一个类创建一个单元测试,你会看到差异)。

我在这个测试中使用JunitMockito

所有在jcabi-s3中的类都被@Immutable注解,并且是真正的不可变的。

该库作为一个JAR依赖项在Maven Central中发布(在Maven Central中获取其最新版本)。

如常,欢迎您通过GitHub问题提供您的评论和批评。

Translated by ChatGPT gpt-3.5-turbo/42 on 2023-11-22 at 09:37

sixnines availability badge   GitHub stars