---
title: "Замена кодирования типа состоянием/стратегией"
type: "refactoring-technique"
slug: "replace-type-code-with-state-strategy"
url: "http://localhost:3000/ru/replace-type-code-with-state-strategy.md"
category: "Организация данных"
description: "Проблема: У вас есть закодированный тип, который влияет на поведение, но вы не можете использовать подклассы, чтобы избавиться от него. Решение: Замените кодирование типа объектом-состоянием. При необходимости заменить значение поля с кодированием типа, в него подставляется другой объект-состояние."
---
# Замена кодирования типа состоянием/стратегией

> Проблема: У вас есть закодированный тип, который влияет на поведение, но вы не можете использовать подклассы, чтобы избавиться от него. Решение: Замените кодирование типа объектом-состоянием. При необходимости заменить значение поля с кодированием типа, в него подставляется другой объект-состояние.

## Problem

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

## Solution

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

## Why Refactor

У нас есть кодирование типа, и оно влияет на поведение класса, поэтому мы не можем [заменить кодирования типа классом](/ru/replace-type-code-with-class).

Кодирование типа влияет на поведение класса, но мы не можем создавать подклассы для закодированного типа ввиду наличия существующей иерархии классов или других причин. А значит, не можем применить [замену кодирования типа подклассами](/ru/replace-type-code-with-subclasses).

## Benefits

* Данный рефакторинг предоставляет выход из ситуации, когда поле с закодированным типом меняет своё значение в процессе жизни объекта. В этом случае, замена значения производится путём замены объекта-состояния, на который ссылается исходный класс.
* Если вам потребуется добавить новое значение закодированного типа, все что придётся сделать — это добавить новый подкласс-состояние, не трогая существующий код (_принцип открытости/закрытости_).

## How to Refactor

1. Используйте [самоинкапсуляцию поля](/ru/self-encapsulate-field) для создания геттера для поля, которое содержит кодирование типа.
2. Создайте новый класс и дайте ему понятное название, соответствующее предназначению закодированного типа. Этот класс будет играть роль _состояния_ (или _стратегии_). Создайте в нем абстрактный геттер закодированного поля.
3. Создайте подклассы класса-состояния для каждого значения закодированного типа. В каждом подклассе переопределите геттер закодированного поля так, чтобы он возвращал соответствующее значение закодированного типа.
4. В абстрактном классе состояния, создайте статический фабричный метод, принимающий в параметре значение закодированного типа. В зависимости от этого параметра, фабричный метод будет создавать объекты различных состояний. Для этого в его коде придётся создать большой условный оператор, но он будет единственным по завершению рефакторинга.
5. В исходном классе, поменяйте тип закодированного поля на класс-состояние. В сеттере этого поля, вызывайте фабричный метод состояния для получения новых объектов состояний.
6. Теперь можете начинать перемещать поля и методы из суперкласса в соответствующие подклассы-состояния (при помощи [спуска поля](/ru/push-down-field) и [спуска метода](/ru/push-down-method)).
7. Когда все что можно перемещено, используйте [замену условных операторов полиморфизмом](/ru/replace-conditional-with-polymorphism), чтобы окончательно избавиться от условных операторов, использующий закодированный тип.
## Relations

**Similar techniques**

- [Замена кодирования типа классом](/ru/replace-type-code-with-class.md)
- [Замена кодирования типа подклассами](/ru/replace-type-code-with-subclasses.md)

**Eliminates smells**

- [Одержимость элементарными типами](/ru/smells/primitive-obsession.md)

