Printers Instead of Getters

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

Геттеры и сеттеры это зло. Больше обсуждать нечего, это урегулировано. Вы не согласны? Давайте обсудим это позже. А пока предположим, что мы хотим избавиться от геттеров. Основной вопрос заключается в том, как это вообще возможно? Мы же должны получить данные из объекта, верно? Нет. Неправильно.

Я предлагаю использовать вместо этого “принтеры”. Вместо того чтобы раскрывать данные через геттеры, объект будет обладать функциональностью печати самого себя в определенное место.

Предположим, что это наш класс:

Нам нужно преобразовать это в формат XML. Более или менее традиционный способ сделать это - через геттеры и JAXB.

Это очень оскорбительный способ обращаться с объектом. В основном мы выставляем все, что находится внутри, на показ. Это был хороший, самодостаточный твердый объект, а мы превратили его в сумку с данными, которые любой может получить множеством способов. Мы, конечно, можем получить доступ к нему для чтения.

Удобно иметь эти геттеры, можно сказать. Мы все к ним привыкли. Если мы хотим преобразовать его в JSON, они будут очень полезны. Если мы хотим использовать этот бедный объект в качестве объекта данных в JSP, геттеры помогут нам. В языке Java существует множество примеров, где геттеры активно используются.

Это не потому, что они так эффективны. Это потому, что мы так процедурны в нашем мышлении. Мы не доверяем нашим объектам. Мы доверяем только хранимым данным. Мы не хотим, чтобы объект Book генерировал XML. Мы хотим, чтобы он дал нам данные. Мы сами построим XML. Объект Book слишком глуп, чтобы справиться с этой работой. Мы гораздо умнее!

Я предлагаю перестать думать таким образом. Вместо этого давайте попробуем дать этому бедному Book шанс и оборудуем его “принтером”:

Это не лучшая реализация, но вы поняли идею. Объект больше не раскрывает свои внутренние данные. Мы не можем получить его ISBN и заголовок. Мы можем только попросить его напечатать себя в формате XML.

Мы можем добавить дополнительный принтер, если требуется другой формат:

Снова, не самая лучшая реализация, но вы видите, что я пытаюсь показать. Каждый раз, когда нам нужен новый формат, мы создаем новый принтер.

Вы можете сказать, что объект будет довольно большим, если будет много форматов. Это верно, но большой объект - это плохой дизайн изначально. Я бы сказал, что если есть более одного принтера - это проблема.

Итак, что делать, если нам нужны несколько форматов? Используйте “медиа”, куда можно будет печатать. Скажем, у нас есть объект, который представляет запись в MySQL. Мы хотим, чтобы его можно было напечатать в XML, HTML, JSON, некий двоичный формат и бог знает что еще. Мы можем добавить много таких принтеров к нему, но объект будет большим и уродливым. Чтобы избежать этого, введем новый объект, который представляет среду, куда данные будут печататься:

Снова, это очень примитивный дизайн неизменяемого класса Media, но вы поняли идею - media принимает данные. Теперь мы хотим вывести наш объект в формат JSON (этот дизайн на самом деле не идеален, так как JsonObjectBuilder не является неизменяемым, хотя выглядит так…).

Теперь мы создаем экземпляр JsonMedia и просим нашу книгу напечатать себя там:

Вот и все! Объект JSON готов, и книга не знает, что именно было распечатано только что. Нам нужно распечатать книгу в формате XML? Для этого мы создаем XmlMedia, который будет выводить книгу в формате XML. Класс Book остается маленьким, в то время как сложность объектов “медиа” неограничена.

Моя идея здесь простая - нет геттеров, только принтеры!

Translated by ChatGPT gpt-3.5-turbo/42 on 2023-12-15 at 06:35

sixnines availability badge   GitHub stars