Autumn SALE

Замена простого поля объектом

Также известен как: Replace Data Value with Object

Проблема

В классе (или группе классов) есть поле простого типа. У этого поля есть своё поведение и связанные данные.

Решение

Создайте новый класс, поместите в него старое поле и его поведения, храните объект этого класса в исходном классе.

До
Replace Data Value with Object - Before
После
Replace Data Value with Object - After

Причины рефакторинга

В целом этот рефакторинг является частным случаем извлечения класса. Отличия заключаются в причинах, повлёкших рефакторинг.

В извлечении класса мы имеем один класс, который отвечает за разные вещи, и хотим разделить его ответственность.

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

Поэтому мы создаём для всего этого новый класс и перемещаем в него не только само поле, но и связанные с ним данные и поведения.

Достоинства

  • Улучшает связность внутри классов. Данные и поведения этих данных находятся в одном классе.

Порядок рефакторинга

Перед началом рефакторинга, посмотрите есть ли прямые обращения к полю внутри класса. Если да, примените самоинкапсуляцию поля, чтобы скрыть его в исходном классе.

  1. Создайте новый класс и скопируйте в него ваше поле и его геттер. Кроме того, создайте конструктор, принимающий простое значение этого поля. В этом классе не будет сеттера, так как каждое новое значение поля, подаваемое в оригинальный класс, будет создавать новый объект-значение.

  2. В исходном классе поменяйте тип поля на новый класс.

  3. В его геттере в исходном классе обращайтесь к геттеру связанного объекта.

  4. В сеттере создайте новый объект-значение. Возможно, вам потребуется также создать новый объект в конструкторе, если ранее там задавались какие-то начальные значения для поля.

Последующие шаги

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

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