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:

Метод exec() на @pgsql (я использую pgtk gem) возвращает массив Hashes, которые выглядят так, если мы преобразуем их в JSON:

Было бы замечательно, если бы метод fetch() возвращал массив объектов, а не массив хешей. Таким образом, мой класс Project выглядит следующим образом:

Он идеально подходит для манипуляций с одним проектом:

Два SQL-запроса здесь - это не проблема. Однако, если я преобразую список Хэшей в Проекты таким образом, у меня возникнут серьезные проблемы с производительностью.

Вот что убьет меня в плане производительности:

Этот код будет генерировать слишком много избыточных SQL-запросов. Мы будем делать поездки в PostgreSQL, чтобы получить данные, которые у нас были несколько миллисекунд назад, когда мы выполняли SELECT * FROM project.

Самое простое и очевидное решение, которое многие из вас, возможно, предложат, - это инкапсулировать полученный хэш в объект Project. Другими словами, превратить Project в DTO, хранителя данных. Что ж, в этом случае нам даже не понадобится объект, а можно просто вернуть хэш с данными. Но так мы не хотим проектировать наше объектно-ориентированное программное обеспечение. Мы хотим иметь дело с объектами, а не с структурами данных. И в то же время мы не хотим, чтобы объекты были настолько глупыми, чтобы возвращаться к базе данных за теми же данными, которые у нас были секунду назад. Вот решение, которое я предлагаю:

Этот новый объект Veil из гема veils является декоратором Project. Он ведет себя как Project, но некоторые его методы переопределены: name() и author(). Когда они вызываются, вызовы не достигают инкапсулированного Project. Вместо этого возвращаются данные, хранящиеся в Veil.

Он называется “вуаль”, потому что он действует так же: предустановленные данные возвращаются только до тех пор, пока не будет вызван какой-то другой метод, который не был предустановлен. Если это происходит, вуаль пронзается и объект Veil становится полностью прозрачным, пропуская все вызовы методов.

Таким образом, эффективность DTO сочетается с элегантностью ООП.

Я использую эти новые объекты-вуали в yegor256/codexia, чтобы вы могли видеть, как они работают.

P.S. Я также создаю класс Unpiercable, который ведет себя точно так же, как Veil, но его нельзя пронзить. Это очень полезно, когда вы не ожидаете, что будут происходить взаимодействия, изменяющие данные с объектом, и просто хотите, чтобы некоторые из его методов были предварительно вычислены.

P.P.S. Это реализация для Kotlin.

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

sixnines availability badge   GitHub stars