СДЕЛАЙТЕ СВОИ УРОКИ ЕЩЁ ЭФФЕКТИВНЕЕ, А ЖИЗНЬ СВОБОДНЕЕ

Благодаря готовым учебным материалам для работы в классе и дистанционно

Скидки до 50 % на комплекты
только до

Готовые ключевые этапы урока всегда будут у вас под рукой

Организационный момент

Проверка знаний

Объяснение материала

Закрепление изученного

Итоги урока

Рефакторинг программного обеспечения

Категория: Информатика

Нажмите, чтобы узнать подробности

В данной работе рассматриваются вопросы рефактринга  программного ния. Материал полезен для проведения занятий по дисциплине МДК.04.01." Моделирование и анализ программного обеспечения" специальности 09.02.03 "Программирование в компьютерных системах" СПО углубленной подготовки

Просмотр содержимого документа
«Рефакторинг программного обеспечения»

Рефакторинг программного обеспечения

Рефакторинг программного обеспечения

Типичные недостатки кода Повторяющийся код (Duplicated Code)  Номер один среди недостатков – Повторяющийся код. Если есть два повторяющихся участка кода, то можно быть уверенным, что программа только выиграет, если эти участки перейдут в один.  Простейший случай, когда код повторяется в телах двух методов одного класса. Тогда надо просто применить  Извлечение метода  и вызывать новый метод из всех мест, где повторялся код.  Другой общий случай, когда код повторяется в двух подклассах одного класса. Тогда нужно использовать  Извлечение метода  в обоих подклассах, а затем применить Поднимание метода . Если код похож, но не одинаков, надо использовать  Извлечение метода , чтобы выделить одинаковые части.

Типичные недостатки кода

  • Повторяющийся код (Duplicated Code)

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

Простейший случай, когда код повторяется в телах двух методов одного класса. Тогда надо просто применить  Извлечение метода  и вызывать новый метод из всех мест, где повторялся код.

Другой общий случай, когда код повторяется в двух подклассах одного класса. Тогда нужно использовать  Извлечение метода  в обоих подклассах, а затем применить Поднимание метода . Если код похож, но не одинаков, надо использовать  Извлечение метода , чтобы выделить одинаковые части.

 Затем можно применить  Формирование шаблонного метода . Если методы делают одно и тоже с помощью разных алгоритмов, то надо выбрать лучший и применить  Замену алгоритма .  Если код дублируется в несвязанных классах, можно применить  Извлечение класса  к одному классу, и использовать извлеченный класс в других. Другая возможность состоит в том, что метод принадлежит одному классу и вызывается другим, либо принадлежит какому-либо постороннему классу, и вызывается всеми классами с повторяющимся кодом.  В общем, метод надо выбирать, согласуясь со здравым смыслом – главное, чтобы не было дублирующегося кода.

Затем можно применить  Формирование шаблонного метода . Если методы делают одно и тоже с помощью разных алгоритмов, то надо выбрать лучший и применить  Замену алгоритма .

Если код дублируется в несвязанных классах, можно применить  Извлечение класса  к одному классу, и использовать извлеченный класс в других. Другая возможность состоит в том, что метод принадлежит одному классу и вызывается другим, либо принадлежит какому-либо постороннему классу, и вызывается всеми классами с повторяющимся кодом.

В общем, метод надо выбирать, согласуясь со здравым смыслом – главное, чтобы не было дублирующегося кода.

Длинный метод  Длинные методы сложны для понимания и сопровождения, так что есть смысл в их упрощении и уменьшении.  В 99% случаев применяется  Извлечение метода .  Если в методе большое количество параметров и локальных переменных, то при использовании Извлечения метода в него придется передавать все эти параметры и переменные в виде параметров, что может привести к еще большей путанице. В этом случае можно применить  Замену временной переменной вызовом метода . Длинный список параметров уменьшается с помощью  Передачи объекта целиком  и  Введения объекта параметров . Если вышеперечисленное слабо помогает, то пришло время для  Избавления от метода с помощью объекта метода .
  • Длинный метод

Длинные методы сложны для понимания и сопровождения, так что есть смысл в их упрощении и уменьшении.

В 99% случаев применяется  Извлечение метода .

Если в методе большое количество параметров и локальных переменных, то при использовании Извлечения метода в него придется передавать все эти параметры и переменные в виде параметров, что может привести к еще большей путанице. В этом случае можно применить  Замену временной переменной вызовом метода . Длинный список параметров уменьшается с помощью  Передачи объекта целиком  и  Введения объекта параметров . Если вышеперечисленное слабо помогает, то пришло время для  Избавления от метода с помощью объекта метода .

 Как выбрать код для извлечения? Очень полезно ознакомиться с комментариями: кусок кода с комментариями, объясняющими, что происходит, заменяется на метод с таким же содержательным названием. Можно извлекать даже отдельную строку, если она нуждается в объяснении.  Также используется  Декомпозиция условий  для упрощения логических выражений.

Как выбрать код для извлечения? Очень полезно ознакомиться с комментариями: кусок кода с комментариями, объясняющими, что происходит, заменяется на метод с таким же содержательным названием. Можно извлекать даже отдельную строку, если она нуждается в объяснении.

Также используется  Декомпозиция условий  для упрощения логических выражений.

Большой класс  Когда класс пытается отвечать за все, возникает огромное количество его экземпляров, а отсюда недалеко и до повторяющегося кода.  Решение –  Извлечение класса  либо  Извлечение подкласса . Для применения этих рефакторингов надо выбрать членов класса, которые будут из него удалены. Иногда полезно применить эти рефакторинги несколько раз.  Также бывает полезно рассмотреть, как клиенты используют методы класса и применить  Извлечение интерфейса  – это может натолкнуть на идею, как поделить класс на части.  Если этим большим классом является класс, описывающий пользовательский интерфейс, надо перенести данные и поведение в класс предметной области, воспользовавшись  Дублированием данных пользовательского интерфейса .  
  • Большой класс

Когда класс пытается отвечать за все, возникает огромное количество его экземпляров, а отсюда недалеко и до повторяющегося кода.

Решение –  Извлечение класса  либо  Извлечение подкласса . Для применения этих рефакторингов надо выбрать членов класса, которые будут из него удалены. Иногда полезно применить эти рефакторинги несколько раз.

Также бывает полезно рассмотреть, как клиенты используют методы класса и применить  Извлечение интерфейса  – это может натолкнуть на идею, как поделить класс на части.

Если этим большим классом является класс, описывающий пользовательский интерфейс, надо перенести данные и поведение в класс предметной области, воспользовавшись  Дублированием данных пользовательского интерфейса .

 

Длинный список параметров  Длинные списки параметров неудобны в обращении: их трудно понимать и их постоянно приходится менять при смене информации, которая нужна методу.  Использование  Замены параметра вызовом метода  позволяет заменить параметр на запрос к известному объекту. Использование  Передачи объекта целиком  заменяет передачу отдельных частей объект передачей всего объекта сразу. Если передается связный набор данных, не принадлежащий к какому-либо объекту, спасает использование  Введения объекта параметров .  Но надо помнить, делая эти замены, что они вносят в систему новые зависимости между объектом-хозяином метода и используемыми в методе объектами. Если появление этих зависимостей нежелательно, то можно передавать параметры по старому. Если же списки параметров слишком длинны, либо их изменения слишком часты, то надо заново обдумывать структуру зависимостей в программе.
  • Длинный список параметров

Длинные списки параметров неудобны в обращении: их трудно понимать и их постоянно приходится менять при смене информации, которая нужна методу.

Использование  Замены параметра вызовом метода  позволяет заменить параметр на запрос к известному объекту. Использование  Передачи объекта целиком  заменяет передачу отдельных частей объект передачей всего объекта сразу. Если передается связный набор данных, не принадлежащий к какому-либо объекту, спасает использование  Введения объекта параметров .

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

Различное изменение класса   Такие изменения возникают, когда один класс постоянно изменяется различным образом в связи с различными причинами. Гораздо лучше, когда один класс подвержен изменениям только в связи с одной деятельностью, и когда любое изменение условий затрагивает только один класс.  Решается проблема с помощью  Извлечения класса  для множеств членов класса, зависящих от одного типа изменеий.
  • Различное изменение класса

Такие изменения возникают, когда один класс постоянно изменяется различным образом в связи с различными причинами. Гораздо лучше, когда один класс подвержен изменениям только в связи с одной деятельностью, и когда любое изменение условий затрагивает только один класс.

Решается проблема с помощью  Извлечения класса  для множеств членов класса, зависящих от одного типа изменеий.

Изменение многих классов  Изменение многих классов – это обратное явление к Различным изменениям класса. То есть, если при каждом изменении надо внести кучу переделок в большое количество разных классов, то в конце концов какая-нибудь переделка забудется и все благополучно перестанет работать.  Для борьбы со злом надо использовать  Перемещение поля  и  Перемещение метода  для скопления изменяющихся членов в одном классе. Если подходящего класса нет, надо его создать. Иногда полезно применить  Встраивание класса , добавив один зависящий от изменений данного типа класс к другому. Вследствие этого можно получить легкую дозу  Различных изменений класса , но зачастую с этим легче иметь дело, чем с человеконенавистническими способами лечения.
  • Изменение многих классов

Изменение многих классов – это обратное явление к Различным изменениям класса. То есть, если при каждом изменении надо внести кучу переделок в большое количество разных классов, то в конце концов какая-нибудь переделка забудется и все благополучно перестанет работать.

Для борьбы со злом надо использовать  Перемещение поля  и  Перемещение метода  для скопления изменяющихся членов в одном классе. Если подходящего класса нет, надо его создать. Иногда полезно применить  Встраивание класса , добавив один зависящий от изменений данного типа класс к другому. Вследствие этого можно получить легкую дозу  Различных изменений класса , но зачастую с этим легче иметь дело, чем с человеконенавистническими способами лечения.

Зависть к чужим членам класса  Обычная ситуация: метод заинтересован в членах класса, отличного от того, к которому он принадлежит гораздо больше, чем в членах своего класса. Тогда  Перемещение метода – очевидное решение. Иногда только часть метода страдает от зависти – тогда  Извлечение метода  применяется к страдающей части, затем  Перемещение метода  для переноса получившегося метода в дом его мечты.  Если метод использует части многих классов, то помещается в том, который он использует больше других, либо делится и разносится по этим классам.
  • Зависть к чужим членам класса

Обычная ситуация: метод заинтересован в членах класса, отличного от того, к которому он принадлежит гораздо больше, чем в членах своего класса. Тогда  Перемещение метода – очевидное решение. Иногда только часть метода страдает от зависти – тогда  Извлечение метода  применяется к страдающей части, затем  Перемещение метода  для переноса получившегося метода в дом его мечты.

Если метод использует части многих классов, то помещается в том, который он использует больше других, либо делится и разносится по этим классам.

Пучки данных   Данные нередко группируются вместе: то как поля класса, то как параметры метода. Такой набор данных имеет смысл выделить в отдельный объект с помощью  Извлечения класса . Если эти данные встречаются в вызовах методов, можно воспользоваться  Передачей объекта целиком  или  Введением объекта параметров .  Хорошая проверка пучковости – посмотреть, что получиться, если удалить одно из входящих в пучок полей. Если остальные при этом потеряют смысл, значит данные действительно надо группировать. Вместе с полями в новые объекты переносятся и методы, которые их обрабатывают.
  • Пучки данных

Данные нередко группируются вместе: то как поля класса, то как параметры метода. Такой набор данных имеет смысл выделить в отдельный объект с помощью  Извлечения класса . Если эти данные встречаются в вызовах методов, можно воспользоваться  Передачей объекта целиком  или  Введением объекта параметров .

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

Мания примитивизма   Большинство языков программирования имеют два вида данных: примитивные типы и записи.  Одно из ценных свойств объектов заключается в том, что они стирают границу примитивными типами и большими классами. Можно легко использовать маленькие объекты, которые будут неотличимы от примитивных типов языка.  Этому способствуют:  Замещение поля объектом  для отдельных полей,  Замена кодирования типа классом  для кодирования типа, не влияющее на поведение,  Замена кодирования типа подклассом  либо  Замена кодирования типа Состоянием/Стратегией  для кодирования типа, которое влияет.  Если есть группа полей, которые должны быть вместе, не надо этому мешать –  Извлечение класса . Если примитивы расположились в списках параметров –  Введение объекта параметров , если попали массив –  Замена массива на объект .
  • Мания примитивизма

Большинство языков программирования имеют два вида данных: примитивные типы и записи.

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

Этому способствуют:  Замещение поля объектом  для отдельных полей,  Замена кодирования типа классом  для кодирования типа, не влияющее на поведение,  Замена кодирования типа подклассом  либо  Замена кодирования типа Состоянием/Стратегией  для кодирования типа, которое влияет.

Если есть группа полей, которые должны быть вместе, не надо этому мешать –  Извлечение класса . Если примитивы расположились в списках параметров –  Введение объекта параметров , если попали массив –  Замена массива на объект .

Операторы выбора  Отличительный признак хорошей объектно-ориентированной программы – относительно небольшое количество операторов выбора. Основная проблема с этими операторами в дублирующемся коде: если такие операторы разбросаны по всей программе, и добавляется новый вариант выбора, то надо найти все эти операторы и изменить их. Полиморфизм предоставляет красивый выход из этой ситуации.  В большинстве случаев, когда возникает оператор выбора, надо рассматривать применение полиморфизма.  Если оператор основан на кодировании типа, и нужен класс, который будет соответствовать определенному значению – тогда применяется  Извлечение метода , чтобы вынести этот оператор, и  Перемещение метода  для помещения его в класс, где требуется полиморфизм.
  • Операторы выбора

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

В большинстве случаев, когда возникает оператор выбора, надо рассматривать применение полиморфизма.

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

Здесь надо выбрать между  Заменой кодирования типа подклассами  и  Заменой кодирования типа состоянием/стратегией . Когда структура наследования будет установлена, можно использовать  Замену условия полиморфизмом . Если же имеется немного альтернатив, влияющих на один метод, и изменения не ожидаются, то полиморфизм излишен. В этом случае надо использовать  Замену параметра набором методов . Если среди возможных альтернатив есть NULL, то надо использовать  Введение NULL объекта .
  • Здесь надо выбрать между  Заменой кодирования типа подклассами  и  Заменой кодирования типа состоянием/стратегией . Когда структура наследования будет установлена, можно использовать  Замену условия полиморфизмом .
  • Если же имеется немного альтернатив, влияющих на один метод, и изменения не ожидаются, то полиморфизм излишен. В этом случае надо использовать  Замену параметра набором методов . Если среди возможных альтернатив есть NULL, то надо использовать  Введение NULL объекта .
Параллельные иерархии наследования  Параллельная иерархия – частный случай изменения многих классов: каждый раз, когда надо создать подкласс какого-либо класса, приходится создавать подкласс и у другого. Признаком этого может служить повторение префиксов имен в двух иерархиях.  Общая стратегия избавления от этого недостатка – увериться в том, что экземпляры одной иерархии ссылаются на экземпляры другой. После использования  Перемещения метода  и  Перемещения поля  иерархия ссылающихся классов исчезает.
  • Параллельные иерархии наследования

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

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

Ленивый класс   Каждый класс требует затрат на понимание и поддержку, поэтому классы, которые не делают достаточно, чтобы уделять им отдельное внимание, должны быть уничтожены.  Такая ситуация может сложиться, если класс был задуман как полнофункциональный, но в результате рефакторинга ужался до неприличных размеров, либо класс добавили в расчете на некие будущие разработки, до которых руки так и не дошли.  Если ленивость касается подклассов, используется  Уничтожение иерархии , если просто классов, используется  Встраивание класса .
  • Ленивый класс

Каждый класс требует затрат на понимание и поддержку, поэтому классы, которые не делают достаточно, чтобы уделять им отдельное внимание, должны быть уничтожены.

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

Если ленивость касается подклассов, используется  Уничтожение иерархии , если просто классов, используется  Встраивание класса .

Спекулятивная общность  Ситуация возникает, когда ведется широкомасштабная подготовка к реализации кучи возможностей, которые так и не воплощаются в жизнь. В результате приходится выметать эти излишние приготовления.  Метлами служат:  Уничтожение иерархии  при ненужном наследовании,  Встраивание класса  при бесполезном делегировании,  Избавление от параметра  при лишних параметрах,  Переименование метода  при слишком общих и непонятных именах методов
  • Спекулятивная общность

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

Метлами служат:  Уничтожение иерархии  при ненужном наследовании,  Встраивание класса  при бесполезном делегировании,  Избавление от параметра  при лишних параметрах,  Переименование метода  при слишком общих и непонятных именах методов

Временное поле   Иногда некоторые поля нужны объекту только при определенных обстоятельствах. Такое положение вещей трудно понимаемо, так как ожидается, что объекту нужны все его поля.  Для борьбы с этой напастью можно использовать  Извлечение класса , предоставляя сироткам их собственный дом. Здесь же можно избавить от проверки на NULL, с помощью  Введения NULL объекта .  Этот случай возникает, когда сложному алгоритму нужно много переменных. Если имеется список параметров, переменные описываются как поля, при этом эти поля имеют смысл только во время работы алгоритма. В этом случае снова пригодится  Извлечение класса , чтобы вытащить эти поля вместе с методом, который их использует – получится объект метода.
  • Временное поле

Иногда некоторые поля нужны объекту только при определенных обстоятельствах. Такое положение вещей трудно понимаемо, так как ожидается, что объекту нужны все его поля.

Для борьбы с этой напастью можно использовать  Извлечение класса , предоставляя сироткам их собственный дом. Здесь же можно избавить от проверки на NULL, с помощью  Введения NULL объекта .

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

Цепочки вызовов  Цепочка вызовов – это когда клиент спрашивает какой-то объект о другом объекте, другой объект еще об одном и так далее. Пользование таким путем означает, что клиент зависит от всего пути, и любые изменения в промежуточных звеньях заставят клиента также измениться.  Выход –  Скрывание делегирующего класса . Применить этот рефакторинг можно к различным частям цепи. В принципе, можно применить и ко всем звеньям, но тогда все объекты в цепи станут промежуточными серверами. Зачастую лучшим выходом является рассмотрение, для чего используется результирующий объект. Может быть, имеет смысл использовать  Извлечение метода , чтобы выделить эту функциональность, а затем применить  Перемещение метода  для передвижения получившегося метода назад по цепи.
  • Цепочки вызовов

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

Выход –  Скрывание делегирующего класса . Применить этот рефакторинг можно к различным частям цепи. В принципе, можно применить и ко всем звеньям, но тогда все объекты в цепи станут промежуточными серверами. Зачастую лучшим выходом является рассмотрение, для чего используется результирующий объект. Может быть, имеет смысл использовать  Извлечение метода , чтобы выделить эту функциональность, а затем применить  Перемещение метода  для передвижения получившегося метода назад по цепи.

Промежуточный сервер   Одно из главных преимуществ объектов – инкапсуляция – сокрытие внутренних деталей. Инкапсуляция идет рука об руку с делегированием.  Бывают классы, у которых большинство методов состоят только из вызова метода другого класса. Это значит, что пришло время использовать  Избавление от промежуточного сервера  и обращаться напрямую к объекту, который реально знает, что происходит. Можно воспользоваться также  Встраиванием метода , встроив делегирующий метод в тела вызывающих его методов. Если имеет место добавочное поведение, поможет  Замена делегирования наследованием  для описания промежуточного сервера как подкласса того класса, который он расширяет.
  • Промежуточный сервер

Одно из главных преимуществ объектов – инкапсуляция – сокрытие внутренних деталей. Инкапсуляция идет рука об руку с делегированием.

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

Излишняя скрытость  Лечение:  Перемещение поля ,  Перемещение метода  для передвижения членов туда, где они нужнее;  Замена двунаправленной связи на однонаправленную  для упрощения структуры связей;  Извлечение класса , если у нескольких классов есть общая потребность в чем-то (пусть все вместе используют новый класс);  Скрывание делегирующего класса  для установления посредника.  Подклассы зачастую хотят знать о родителях гораздо больше, чем то, о чем им могут поведать. Раз так, пригодится  Замена наследования делегированием .
  • Излишняя скрытость

Лечение:  Перемещение поляПеремещение метода  для передвижения членов туда, где они нужнее;  Замена двунаправленной связи на однонаправленную  для упрощения структуры связей;  Извлечение класса , если у нескольких классов есть общая потребность в чем-то (пусть все вместе используют новый класс);  Скрывание делегирующего класса  для установления посредника.

Подклассы зачастую хотят знать о родителях гораздо больше, чем то, о чем им могут поведать. Раз так, пригодится  Замена наследования делегированием .

Альтернативные классы с разными интерфейсами  Пусть есть два класса, в которых часть функциональности общая, но методы, реализующие ее, имеют разные параметры.  Тогда используется  Переименование методов , чтобы методы, делающие одно и тоже, назывались одинаково. Далее –  Перемещение метода , чтобы интерфейсы, обеспечивающие функциональность, стали одинаковыми. Если при этом надо перемещать слишком много кода, надо задуматься об  Извлечении суперкласса .
  • Альтернативные классы с разными интерфейсами

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

Тогда используется  Переименование методов , чтобы методы, делающие одно и тоже, назывались одинаково. Далее –  Перемещение метода , чтобы интерфейсы, обеспечивающие функциональность, стали одинаковыми. Если при этом надо перемещать слишком много кода, надо задуматься об  Извлечении суперкласса .

Неполный библиотечный класс  Если кем-то реализован набор классов, то, как правило, через некоторое время он перестает удовлетворять требованиям пользователей. Естественное решение – поменять кое-что в этой библиотеке, но вся беда в том, что эти классы не изменить. Тогда используется пара рефакторингов, специально предназначенных для этой цели.  Если надо добавить пару методов, используется  Введение внешнего метода . Если надо серьезно поменять поведение класса, используется  Введение локального расширения .
  • Неполный библиотечный класс

Если кем-то реализован набор классов, то, как правило, через некоторое время он перестает удовлетворять требованиям пользователей. Естественное решение – поменять кое-что в этой библиотеке, но вся беда в том, что эти классы не изменить. Тогда используется пара рефакторингов, специально предназначенных для этой цели.

Если надо добавить пару методов, используется  Введение внешнего метода . Если надо серьезно поменять поведение класса, используется  Введение локального расширения .

Класс данных   Это класс, в котором есть поля методы, методы выборки и установки значений (Get и Set методы), и больше ничего. Функционально это просто контейнеры для данных, используемые другими классами.  На начальных стадиях разработки поля могут быть публичными. Если так, надо применить  Инкапсулирование поля . Если есть коллекция, надо проверить правильность ее инкапсулирования. Если она инкапсулирована неправильно, необходимо применить  Инкапсулирование коллекции . Если поля не должны изменяться, надо использовать  Избавление от метода установки значения .  Далее нужно проверить, где используются методы выборки и установки значений данного класса. В этих местах можно использовать  Перемещение метода , чтобы передвинуть поведение в класс данных. Если нет смысла двигать весь метод, можно воспользоваться  Извлечением метода , чтобы выделить метод, который можно переместить.
  • Класс данных

Это класс, в котором есть поля методы, методы выборки и установки значений (Get и Set методы), и больше ничего. Функционально это просто контейнеры для данных, используемые другими классами.

На начальных стадиях разработки поля могут быть публичными. Если так, надо применить  Инкапсулирование поля . Если есть коллекция, надо проверить правильность ее инкапсулирования. Если она инкапсулирована неправильно, необходимо применить  Инкапсулирование коллекции . Если поля не должны изменяться, надо использовать  Избавление от метода установки значения .

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

Отказ от наследства  Подклассы получают от своих родителей множество наследуемых полей и методов, но выбирают только часть из них.  Обычная история – иерархия неверна. В этом случае создается еще один подкласс суперкласса и используются  Спускание метода  и  Спускание поля  с тем расчетом, чтобы в суперклассе остались только общие члены.  Особый случай, когда подкласс не хочет поддерживать интерфейс суперкласса. Тогда надо применять  Замену наследования делегированием .
  • Отказ от наследства

Подклассы получают от своих родителей множество наследуемых полей и методов, но выбирают только часть из них.

Обычная история – иерархия неверна. В этом случае создается еще один подкласс суперкласса и используются  Спускание метода  и  Спускание поля  с тем расчетом, чтобы в суперклассе остались только общие члены.

Особый случай, когда подкласс не хочет поддерживать интерфейс суперкласса. Тогда надо применять  Замену наследования делегированием .