Yet Another Evil Suffix For Object Names: Client

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

一段时间前,我们讨论了对象和类名中的“-ER”后缀。我们一致认为它们是邪恶的,如果我们希望我们的代码真正面向对象,并且我们的对象是对象而不是过程的集合,那么我们必须避免使用它们。现在我准备介绍一个新的邪恶后缀:“Client”。

让我先举一个例子。下面是一个带有这种后缀的对象的样子(这是AWS Java SDKAmazonS3Client的伪代码版本):

所有的“客户端”看起来都很相似:它们使用一些访问凭证封装目标URL,并公开一些方法,用于将数据传输到/从“服务器”。尽管这种设计看起来像一个合适的对象,但它实际上并没有真正遵循面向对象的真正精神。这就是为什么它不像应该的那样易于维护的两个原因。

  • 它以数据为中心。客户端与服务器之间的关系的核心在于数据的传输。以AWS S3服务的HTTP RESTful API为例。在AWS端存在各种实体,如存储桶(buckets)、对象(objects)、版本(versions)、访问控制策略等,而服务器将它们转化为JSON/XML数据。然后数据传递到我们这边,我们的客户端处理JSON或XML。对于我们来说,它始终只是数据,永远不会真正成为存储桶、对象或版本。

后果取决于情况,但以下是最有可能的:

  • 重复代码。如果我们决定保持面向对象的方式,我们就必须将客户端返回的数据转换为对象。很可能这会导致多个项目中的代码重复。我在开始使用S3 SDK时也遇到了这个问题。很快我意识到,为了避免重复,最好创建一个库来将S3 SDK数据转换为对象:jcabi-s3

  • 测试的困难。由于客户端在大多数情况下是一个相当大的类/接口,所以在单元测试中模拟它或创建其测试替身/虚拟对象是一项相当复杂的任务。

  • 静态问题。尽管客户类的方法并非静态的,但它们与实用类非常相似,后者因反对面向对象编程而闻名。我们对实用类的问题与我们对“客户”类的问题几乎相同。

  • 可扩展性问题。无需多言,当客户端对象拥有160多个方法并且不断增长时,几乎不可能对其进行装饰。唯一可能的添加新功能的方式是创建新方法。最终,我们得到一个怪物类,无法在不修改的情况下重新使用。

替代方案是什么?

正确的设计是用客户端对象来替换”clients”,这些对象代表的是服务器端的实体,而不是整个服务器。例如,使用S3 SDK,可以是BucketObjectVersionPolicy等。它们每个都暴露了真实的存储桶对象版本的功能,这些功能是AWS S3可以提供的。

当然,我们需要一个高级对象来代表整个API/服务器,但它应该很小。例如,在S3 SDK示例中,可以称之为Region,表示整个AWS地区及其存储桶。然后,我们可以从中检索一个存储桶,就不再需要地区了。然后,要列出存储桶中的对象,我们要求存储桶为我们执行此操作。每次都不需要与整个”服务器对象”进行通信,即使从技术上讲,这样的通信当然是存在的。

总之,问题不仅仅在于名称后缀,而是在于在客户端代表整个服务器而不是其实体的整个思想上。这样的抽象方法1)太庞大,2)非常数据驱动。

顺便提一下,查看一些没有”client”对象的面向对象客户端的JCabi库(Java)的示例:jcabi-githubjcabi-dynamojcabi-s3jcabi-simpledb

Translated by ChatGPT gpt-3.5-turbo/42 on 2023-11-17 at 16:58

sixnines availability badge   GitHub stars