---
title: "Substituir Método por Objeto de Método"
type: "refactoring-technique"
slug: "replace-method-with-method-object"
url: "http://localhost:3000/pt-br/replace-method-with-method-object.md"
category: "Composing Methods"
description: "Problema: Você tem um método longo cujas variáveis locais estão tão entrelaçadas que não é possível aplicar Extrair Método. Solução: Transforme o método em uma classe separada para que as variáveis locais se tornem campos da classe. Então você pode dividir o método em vários métodos dentro da mesma classe."
languages: ["java", "csharp", "php", "python", "typescript"]
---
# Substituir Método por Objeto de Método

> Problema: Você tem um método longo cujas variáveis locais estão tão entrelaçadas que não é possível aplicar Extrair Método. Solução: Transforme o método em uma classe separada para que as variáveis locais se tornem campos da classe. Então você pode dividir o método em vários métodos dentro da mesma classe.

## Problem

Você tem um método longo cujas variáveis locais estão tão entrelaçadas que não é possível aplicar _Extrair Método_.

## Solution

Transforme o método em uma classe separada para que as variáveis locais se tornem campos da classe. Então você pode dividir o método em vários métodos dentro da mesma classe.

## Why Refactor

Um método é longo demais e você não consegue separá-lo por causa de massas emaranhadas de variáveis locais difíceis de isolar umas das outras.

O primeiro passo é isolar o método inteiro em uma classe separada e transformar suas variáveis locais em campos da classe.

Em primeiro lugar, isso permite isolar o problema no nível da classe. Em segundo lugar, abre caminho para dividir um método grande e difícil de manejar em outros menores que, de qualquer forma, não se encaixariam no propósito da classe original.

## Benefits

* Isolar um método longo em sua própria classe permite impedir que um método cresça descontroladamente de tamanho. Isso também permite dividi-lo em submétodos dentro da classe, sem poluir a classe original com métodos utilitários.

## How to Refactor

1. Crie uma nova classe. Dê a ela um nome baseado no propósito do método que você está refatorando.
2. Na nova classe, crie um campo privado para armazenar uma referência a uma instância da classe na qual o método estava localizado anteriormente. Ele pode ser usado para obter alguns dados necessários da classe original, se preciso.
3. Crie um campo privado separado para cada variável local do método.
4. Crie um construtor que aceite como parâmetros os valores de todas as variáveis locais do método e também inicialize os campos privados correspondentes.
5. Declare o método principal e copie para ele o código do método original, substituindo as variáveis locais pelos campos privados.
6. Substitua o corpo do método original na classe original criando um objeto de método e chamando seu método principal.
## Relations

**Similar techniques**

- [Substituir Valor de Dado por Objeto](/pt-br/replace-data-value-with-object.md)

**Eliminates smells**

- [Método Longo](/pt-br/smells/long-method.md)

## Code Examples

### java

```java
// Before
class Order {
  // ...
  public double price() {
    double primaryBasePrice;
    double secondaryBasePrice;
    double tertiaryBasePrice;
    // Realize uma computação longa.
  }
}

// After
class Order {
  // ...
  public double price() {
    return new PriceCalculator(this).compute();
  }
}

class PriceCalculator {
  private double primaryBasePrice;
  private double secondaryBasePrice;
  private double tertiaryBasePrice;
  
  public PriceCalculator(Order order) {
    // Copie informações relevantes do
    // objeto order.
  }
  
  public double compute() {
    // Realize uma computação longa.
  }
}
```

### csharp

```csharp
// Before
public class Order 
{
  // ...
  public double Price() 
  {
    double primaryBasePrice;
    double secondaryBasePrice;
    double tertiaryBasePrice;
    // Realize uma computação longa.
  }
}

// After
public class Order 
{
  // ...
  public double Price() 
  {
    return new PriceCalculator(this).Compute();
  }
}

public class PriceCalculator 
{
  private double primaryBasePrice;
  private double secondaryBasePrice;
  private double tertiaryBasePrice;
  
  public PriceCalculator(Order order) 
  {
    // Copie informações relevantes do
    // objeto order.
  }
  
  public double Compute() 
  {
    // Realize uma computação longa.
  }
}
```

### php

```php
// Before
class Order {
  // ...
  public function price() {
    $primaryBasePrice = 10;
    $secondaryBasePrice = 20;
    $tertiaryBasePrice = 30;
    // Realize uma computação longa.
  }
}

// After
class Order {
  // ...
  public function price() {
    return (new PriceCalculator($this))->compute();
  }
}

class PriceCalculator {
  private $primaryBasePrice;
  private $secondaryBasePrice;
  private $tertiaryBasePrice;
  
  public function __construct(Order $order) {
      // Copie informações relevantes do
      // objeto order.
  }
  
  public function compute() {
    // Realize uma computação longa.
  }
}
```

### python

```python
// Before
class Order:
    # ...
    def price(self):
        primaryBasePrice = 0
        secondaryBasePrice = 0
        tertiaryBasePrice = 0
        # Realize uma computação longa.

// After
class Order:
    # ...
    def price(self):
        return PriceCalculator(self).compute()


class PriceCalculator:
    def __init__(self, order):
        self._primaryBasePrice = 0
        self._secondaryBasePrice = 0
        self._tertiaryBasePrice = 0
        # Copie informações relevantes do
        # objeto order.

    def compute(self):
        # Realize uma computação longa.
```

### typescript

```typescript
// Before
class Order {
  // ...
  price(): number {
    let primaryBasePrice;
    let secondaryBasePrice;
    let tertiaryBasePrice;
    // Realize uma computação longa.
  }
}

// After
class Order {
  // ...
  price(): number {
    return new PriceCalculator(this).compute();
  }
}

class PriceCalculator {
  private _primaryBasePrice: number;
  private _secondaryBasePrice: number;
  private _tertiaryBasePrice: number;
  
  constructor(order: Order) {
    // Copie informações relevantes do
    // objeto order.
  }
  
  compute(): number {
    // Realize uma computação longa.
  }
}
```

