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