---
title: "Замена конструктора фабричным методом"
type: "refactoring-technique"
slug: "replace-constructor-with-factory-method"
url: "http://localhost:3000/ru/replace-constructor-with-factory-method.md"
category: "Упрощение вызовов методов"
description: "Проблема: У вас есть сложный конструктор, делающий нечто большее, чем простая установка значений полей объекта. Решение: Создайте фабричный метод и замените им вызовы конструктора."
languages: ["java", "csharp", "php", "typescript"]
---
# Замена конструктора фабричным методом

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

## Problem

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

## Solution

Создайте фабричный метод и замените им вызовы конструктора.

## Why Refactor

Самая очевидная причина применения этого рефакторинга связана с [заменой кодирования типа подклассами](/ru/replace-type-code-with-subclasses).

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

Фабричные методы можно использовать и в других ситуациях, когда возможностей конструкторов оказывается недостаточно. Они важны при [замене значения ссылкой](/ru/change-value-to-reference). Их можно также применять для задания различных режимов создания, выходящих за рамки числа и типов параметров.

## Benefits

* Фабричный метод не обязательно возвращает объект того класса, в котором он был вызван. Зачастую это могут быть его подклассы, выбираемые в зависимости от подаваемых в метод аргументов.
* Фабричный метод может иметь более удачное имя, описывающее, что и каким образом он возвращает, например, `Troops::GetCrew(myTank)`.
* Фабричный метод может вернуть уже созданный объект в отличие от конструктора, который всегда создает новый экземпляр.

## How to Refactor

1. Создайте фабричный метод. Поместите в него вызов текущего конструктора.
2. Замените все вызовы конструктора вызовами фабричного метода.
3. Объявите конструктор приватным.
4. Обследуйте код конструктора и попытайтесь вынести в фабричный метод тот код, который не относится к непосредственному конструированию объекта текущего класса.
## Relations

**Helps you do**

- [Замена значения ссылкой](/ru/change-value-to-reference.md)
- [Замена кодирования типа подклассами](/ru/replace-type-code-with-subclasses.md)

## Code Examples

### java

```java
// Before
class Employee {
  Employee(int type) {
    this.type = type;
  }
  // ...
}

// After
class Employee {
  static Employee create(int type) {
    employee = new Employee(type);
    // do some heavy lifting.
    return employee;
  }
  // ...
}
```

### csharp

```csharp
// Before
public class Employee 
{
  public Employee(int type) 
  {
    this.type = type;
  }
  // ...
}

// After
public class Employee
{
  public static Employee Create(int type)
  {
    employee = new Employee(type);
    // Do some heavy lifting.
    return employee;
  }
  // ...
}
```

### php

```php
// Before
class Employee {
  // ...
  public function __construct($type) {
   $this->type = $type;
  }
  // ...
}

// After
class Employee {
  // ...
  static public function create($type) {
    $employee = new Employee($type);
    // do some heavy lifting.
    return $employee;
  }
  // ...
}
```

### typescript

```typescript
// Before
class Employee {
  constructor(type: number) {
    this.type = type;
  }
  // ...
}

// After
class Employee {
  static create(type: number): Employee {
    let employee = new Employee(type);
    // Do some heavy lifting.
    return employee;
  }
  // ...
}
```

