---
title: "Poltergeist (programmation informatique)"
type: "antipattern"
slug: "poltergeist"
url: "http://localhost:3000/fr/antipatterns/poltergeist.md"
description: "Objet éphémère inapproprié"
---
# Poltergeist (programmation informatique)

> Objet éphémère inapproprié

En [programmation informatique](https://en.wikipedia.org/wiki/Computer%5Fprogramming "Computer programming"), un **poltergeist** (ou **roulotte de gitan**) est un objet éphémère, généralement [sans état](https://en.wikipedia.org/wiki/State%5F%28computer%5Fscience%29 "State (computer science)"), utilisé pour effectuer une initialisation ou pour invoquer des méthodes dans une autre classe plus permanente. Il est considéré comme un [anti-pattern](https://en.wikipedia.org/wiki/Anti-pattern "Anti-pattern"). La définition originale est due à Michael Akroyd, lors de la conférence Object World West de 1996 :

> De même qu'une [roulotte de gitan](https://en.wikipedia.org/wiki/Vardo%5F%28Romani%5Fwagon%29 "Vardo (Romani wagon)") ou un [poltergeist](https://en.wikipedia.org/wiki/Poltergeist "Poltergeist") apparaît et disparaît mystérieusement, il en va de même de cet objet à courte durée de vie. En conséquence, le code est plus difficile à maintenir et l'on gaspille inutilement des ressources. La cause habituelle de cet anti-pattern est une mauvaise conception des objets.

Un poltergeist peut souvent être identifié par son nom ; ces noms contiennent fréquemment des mots tels que « Manager », « Controller », « Supervisor », « StartProcess », etc.

Parfois, des classes poltergeist sont créées parce que le [programmeur](https://en.wikipedia.org/wiki/Programmer "Programmer") a anticipé le besoin d'une architecture plus complexe. Par exemple, un poltergeist apparaît si une même méthode joue à la fois le rôle de _client_ et d'_invocateur_ dans un [patron de commande](https://en.wikipedia.org/wiki/Command%5Fpattern "Command pattern"), et que le programmeur anticipe la séparation des deux phases. Toutefois, cette architecture plus complexe peut en réalité ne jamais voir le jour.

Les poltergeists ne doivent pas être confondus avec les objets à longue durée de vie et porteurs d'état d'un [patron](https://en.wikipedia.org/wiki/Software%5Fdesign%5Fpattern "Software design pattern") tel que [modèle–vue–contrôleur](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller "Model–view–controller"), ni avec les patrons de séparation en couches tels que le [patron business delegate](https://en.wikipedia.org/wiki/Business%5Fdelegate%5Fpattern "Business delegate pattern").

Pour supprimer un poltergeist, supprimez la classe et insérez ses fonctionnalités dans la classe invoquée, éventuellement par [héritage](https://en.wikipedia.org/wiki/Inheritance%5F%28object-oriented%5Fprogramming%29 "Inheritance (object-oriented programming)") ou sous forme de [mixin](https://en.wikipedia.org/wiki/Mixin "Mixin").

Des méthodes ont été proposées pour détecter les poltergeists dans le code en vue d'une refactorisation.

## Exemple

La classe `Poltergeist` de cet exemple en [C++](https://en.wikipedia.org/wiki/C%2B%2B "C++") peut être considérée comme un « objet poltergeist », car elle n'ajoute ni fonctionnalité ni encapsulation supplémentaire et ne fait qu'accroître la complexité par une abstraction inutile.

import std;

using String = std::string;

// Classe Poltergeist qui ne fait que détenir un pointeur, sans ajouter de comportement utile
class Poltergeist {
private:
    String* s; // pointeur vers une chaîne, mais la classe elle-même ne fait rien d'utile
public:
    explicit Poltergeist(String* s):
        s{s} {}

    ~Poltergeist() {
        delete s;
    }

    [[nodiscard]]
    String get() const noexcept {
        return s;
    }

    // Aucun comportement ni fonctionnalité utile supplémentaire
};

int main() {
    // Crée un objet Poltergeist qui ne fait que détenir un pointeur vers la chaîne
    Poltergeist p(new String("Hello, world!"));

    // Se contente de faire circuler les données sans apporter de valeur
    std::println(*p.get());

    return 0;
}

On pourrait plutôt procéder de manière plus appropriée en utilisant un [pointeur intelligent](https://en.wikipedia.org/wiki/Smart%5Fpointer "Smart pointer").

import std;

using String = std::string;
template <typename T>
using UniquePtr = std::unique_ptr<T>;

// Utiliser directement des pointeurs intelligents pour gérer la mémoire
UniquePtr<String> s = std::make_unique<String>("Hello, World!");
std::println(*s);

Un autre exemple d'objet poltergeist/roulotte de gitan est le suivant, où `UserCreator` est instancié uniquement pour effectuer quelques actions élémentaires.

import std;

using String = std::string;

class UserManager {
public:
    void createUser(const String& name) {
        std::println("User created: {}", name);
    }
};

// La classe poltergeist
class UserCreator {
public:
    explicit UserCreator(const String& name) {
        UserManager manager;
        manager.createUser(name);
    }
};

int main() {
    // Création d'un poltergeist uniquement pour appeler createUser()
    UserCreator("Alice");
    UserCreator("Bob");
}

On pourrait procéder de manière plus appropriée comme suit, en évitant entièrement toute classe poltergeist :

// Éviter entièrement le poltergeist UserCreator
int main() {
    UserManager manager;
    manager.createUser("Alice");
    manager.createUser("Bob");
}
