---
title: "Remplacer une méthode par un objet-méthode"
type: "refactoring-technique"
slug: "replace-method-with-method-object"
url: "http://localhost:3000/fr/replace-method-with-method-object.md"
category: "Composing Methods"
description: "Problème : Vous avez une longue méthode dans laquelle les variables locales sont si entremêlées que vous ne pouvez pas appliquer Extraire une méthode. Solution : Transformez la méthode en une classe distincte afin que les variables locales deviennent des champs de la classe. Vous pourrez alors scinder la méthode en plusieurs méthodes au sein de la même classe."
languages: ["java", "csharp", "php", "python", "typescript"]
---
# Remplacer une méthode par un objet-méthode

> Problème : Vous avez une longue méthode dans laquelle les variables locales sont si entremêlées que vous ne pouvez pas appliquer Extraire une méthode. Solution : Transformez la méthode en une classe distincte afin que les variables locales deviennent des champs de la classe. Vous pourrez alors scinder la méthode en plusieurs méthodes au sein de la même classe.

## Problem

Vous avez une longue méthode dans laquelle les variables locales sont si entremêlées que vous ne pouvez pas appliquer _Extraire une méthode_.

## Solution

Transformez la méthode en une classe distincte afin que les variables locales deviennent des champs de la classe. Vous pourrez alors scinder la méthode en plusieurs méthodes au sein de la même classe.

## Why Refactor

Une méthode est trop longue et vous ne pouvez pas la séparer à cause d'un enchevêtrement de variables locales difficiles à isoler les unes des autres.

La première étape consiste à isoler la méthode entière dans une classe distincte et à transformer ses variables locales en champs de la classe.

D'une part, cela permet d'isoler le problème au niveau de la classe. D'autre part, cela ouvre la voie au découpage d'une méthode volumineuse et peu maniable en méthodes plus petites qui, de toute façon, ne cadreraient pas avec la vocation de la classe d'origine.

## Benefits

* Isoler une longue méthode dans sa propre classe permet d'empêcher une méthode de gonfler démesurément. Cela permet aussi de la scinder en sous-méthodes au sein de la classe, sans polluer la classe d'origine avec des méthodes utilitaires.

## How to Refactor

1. Créez une nouvelle classe. Nommez-la d'après l'objectif de la méthode que vous refactorisez.
2. Dans la nouvelle classe, créez un champ privé destiné à stocker une référence vers une instance de la classe où se trouvait précédemment la méthode. Il pourra servir à récupérer certaines données nécessaires depuis la classe d'origine, le cas échéant.
3. Créez un champ privé distinct pour chaque variable locale de la méthode.
4. Créez un constructeur qui accepte comme paramètres les valeurs de toutes les variables locales de la méthode et qui initialise également les champs privés correspondants.
5. Déclarez la méthode principale et copiez-y le code de la méthode d'origine, en remplaçant les variables locales par les champs privés.
6. Remplacez le corps de la méthode d'origine dans la classe d'origine en créant un objet-méthode et en appelant sa méthode principale.
## Relations

**Similar techniques**

- [Remplacer une donnée par un objet](/fr/replace-data-value-with-object.md)

**Eliminates smells**

- [Méthode longue](/fr/smells/long-method.md)

## Code Examples

### java

```java
// Before
class Order {
  // ...
  public double price() {
    double primaryBasePrice;
    double secondaryBasePrice;
    double tertiaryBasePrice;
    // Effectuer le long calcul.
  }
}

// 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) {
    // Copier les informations pertinentes depuis
    // l'objet order.
  }
  
  public double compute() {
    // Effectuer le long calcul.
  }
}
```

### csharp

```csharp
// Before
public class Order 
{
  // ...
  public double Price() 
  {
    double primaryBasePrice;
    double secondaryBasePrice;
    double tertiaryBasePrice;
    // Effectuer le long calcul.
  }
}

// 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) 
  {
    // Copier les informations pertinentes depuis
    // l'objet order.
  }
  
  public double Compute() 
  {
    // Effectuer le long calcul.
  }
}
```

### php

```php
// Before
class Order {
  // ...
  public function price() {
    $primaryBasePrice = 10;
    $secondaryBasePrice = 20;
    $tertiaryBasePrice = 30;
    // Effectuer le long calcul.
  }
}

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

class PriceCalculator {
  private $primaryBasePrice;
  private $secondaryBasePrice;
  private $tertiaryBasePrice;
  
  public function __construct(Order $order) {
      // Copier les informations pertinentes depuis
      // l'objet order.
  }
  
  public function compute() {
    // Effectuer le long calcul.
  }
}
```

### python

```python
// Before
class Order:
    # ...
    def price(self):
        primaryBasePrice = 0
        secondaryBasePrice = 0
        tertiaryBasePrice = 0
        # Effectuer le long calcul.

// 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
        # Copier les informations pertinentes depuis
        # l'objet order.

    def compute(self):
        # Effectuer le long calcul.
```

### typescript

```typescript
// Before
class Order {
  // ...
  price(): number {
    let primaryBasePrice;
    let secondaryBasePrice;
    let tertiaryBasePrice;
    // Effectuer le long calcul.
  }
}

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

class PriceCalculator {
  private _primaryBasePrice: number;
  private _secondaryBasePrice: number;
  private _tertiaryBasePrice: number;
  
  constructor(order: Order) {
    // Copier les informations pertinentes depuis
    // l'objet order.
  }
  
  compute(): number {
    // Effectuer le long calcul.
  }
}
```

