Veil Objects to Replace DTOs

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

这是我几天前在使用 Codexia,一个 Ruby 网页应用程序时发现的一个新思路。我需要从 PostgreSQL 获取数据行并将对象返回给客户端。对我来说,一直存在一个问题,即如何在不将对象转换为数据传输对象(DTO)的情况下实现这一点。这是我找到的解决方案,并给它起了一个名字:Veil Objects。

假设我从 PostgreSQL 中获取项目列表:

@pgsql上的exec()方法(我正在使用pgtk宝石)返回一个由Hashes组成的数组,如果我们将它们转换为JSON,它们看起来像这样:

将方法 fetch() 返回一个对象数组而不是哈希数组会很好。所以我的类 Project 看起来像这样:

它设计得非常适合单项目操作:

这里有两个SQL请求不是什么大问题。然而,如果我将散列列表转换成项目,我将会遇到严重的性能问题。

这就是会让我在性能上崩溃的原因:

这段代码会生成太多冗余的SQL请求。当我们执行SELECT * FROM project时,我们会往返于PostgreSQL来获取几毫秒前的数据。

最简单、最明显的解决方案是将检索到的哈希封装到Project对象中。换句话说,将Project转换为DTO,一个数据的持有者。好吧,在这种情况下,我们甚至可能不需要一个对象,而是可以返回带有数据的哈希。但这不是我们希望设计面向对象软件的方式。我们希望处理对象,而不是数据结构。同时,我们也不希望对象愚蠢到为了同样的数据回到数据库。这是我提出的解决方案:

这个来自veils gem的新的Veil对象是Project的一个装饰器。它的行为像一个Project,但其中的一些方法被重新定义:name()author()。当调用它们时,调用不会到达封装的Project,而是返回存储在Veil中的数据。

它被称为“veil”是因为它的作用就像一层面纱:预设的数据只有在调用其他未预设的方法之前才会返回。如果发生这种情况,面纱就会被刺破,Veil对象变得完全透明,将所有的方法调用传递。

因此,DTO的效率与OOP的优雅相结合。

我在yegor256/codexia中使用这些新的veil对象,所以你可以看到它们的工作方式。

附言:我还创建了一个Unpiercable类,它的行为与Veil完全相同,但永远不会被刺破。当你不希望对象发生任何修改数据的交互,只想要预先计算一些方法时,它非常有用。

再附言:这是Kotlin的实现

Translated by ChatGPT gpt-3.5-turbo/42 on 2023-11-22 at 10:06

sixnines availability badge   GitHub stars