---
title: "Самоинкапсуляция поля"
type: "refactoring-technique"
slug: "self-encapsulate-field"
url: "http://localhost:3000/ru/self-encapsulate-field.md"
category: "Организация данных"
description: "Проблема: Вы используете прямой доступ к приватным полями внутри класса. Решение: Создайте геттер и сеттер для поля, и пользуйтесь для доступа к полю только ими."
languages: ["java", "csharp", "php", "typescript"]
---
# Самоинкапсуляция поля

> Проблема: Вы используете прямой доступ к приватным полями внутри класса. Решение: Создайте геттер и сеттер для поля, и пользуйтесь для доступа к полю только ими.

## Problem

Вы используете прямой доступ к приватным полями внутри класса.

## Solution

Создайте геттер и сеттер для поля, и пользуйтесь для доступа к полю только ими.

## Why Refactor

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

## Benefits

* _Непрямой доступ к полям_ — это когда работа с полем происходит через методы доступа (геттеры и сеттеры). Этот подход отличается гораздо большей гибкостью, чем _прямой доступ к полям_.

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

## How to Refactor

1. Создайте геттер (и опциональный сеттер) для поля. Они должны быть защищёнными (`protected`) либо публичными (`public`).
2. Найдите все прямые обращения к полю и замените их вызовами геттера и сеттера.
## Relations

**Helps you do**

- [Дублирование видимых данных](/ru/duplicate-observed-data.md)
- [Замена кодирования типа подклассами](/ru/replace-type-code-with-subclasses.md)
- [Замена кодирования типа состоянием/стратегией](/ru/replace-type-code-with-state-strategy.md)

**Similar techniques**

- [Инкапсуляция поля](/ru/encapsulate-field.md)

## Code Examples

### java

```java
// Before
class Range {
  private int low, high;
  boolean includes(int arg) {
    return arg >= low && arg <= high;
  }
}

// After
class Range {
  private int low, high;
  boolean includes(int arg) {
    return arg >= getLow() && arg <= getHigh();
  }
  int getLow() {
    return low;
  }
  int getHigh() {
    return high;
  }
}
```

### csharp

```csharp
// Before
class Range 
{
  private int low, high;
  
  bool Includes(int arg) 
  {
    return arg >= low && arg <= high;
  }
}

// After
class Range 
{
  private int low, high;
  
  int Low {
    get { return low; }
  }
  int High {
    get { return high; }
  }
  
  bool Includes(int arg) 
  {
    return arg >= Low && arg <= High;
  }
}
```

### php

```php
// Before
private $low;
private $high;

function includes($arg) {
  return $arg >= $this->low && $arg <= $this->high;
}

// After
private $low;
private $high;

function includes($arg) {
  return $arg >= $this->getLow() && $arg <= $this->getHigh();
}
function getLow() {
  return $this->low;
}
function getHigh() {
  return $this->high;
}
```

### typescript

```typescript
// Before
class Range {
  private low: number
  private high: number;
  includes(arg: number): boolean {
    return arg >= low && arg <= high;
  }
}

// After
class Range {
  private low: number
  private high: number;
  includes(arg: number): boolean {
    return arg >= getLow() && arg <= getHigh();
  }
  getLow(): number {
    return low;
  }
  getHigh(): number {
    return high;
  }
}
```

