Logotipo do ConstructiCat
CodeBust.
Explorar a seção ▾

Poltergeist.

Um poltergeist é uma classe de vida curta e sem estado que só existe para chamar métodos de outra classe, adicionando indireção sem adicionar comportamento.

Na programação de computadores, um poltergeist é um objeto de vida curta, normalmente sem estado, usado para realizar inicializações ou para invocar métodos em outra classe, mais permanente. É considerado um antipadrão. O termo foi introduzido por Michael Akroyd na Object World West Conference de 1996: como um poltergeist, esse objeto aparece e desaparece misteriosamente. Como consequência, o código fica mais difícil de manter e recursos são desperdiçados sem nenhum benefício. A causa típica desse antipadrão é um projeto de objetos deficiente.

Um poltergeist muitas vezes pode ser identificado pelo nome; eles costumam incluir no nome palavras como "Manager", "Controller", "Supervisor", "StartProcess", etc.

Às vezes, classes poltergeist são criadas porque o programador anteviu a necessidade de uma arquitetura mais complexa. Por exemplo, um poltergeist surge se o mesmo método atua tanto como cliente quanto como invocador em um padrão Command, e o programador antecipa a separação das duas fases. No entanto, essa arquitetura mais complexa pode, na verdade, nunca se concretizar.

Poltergeists não devem ser confundidos com os objetos de vida longa e portadores de estado de um padrão como o model–view–controller, ou de padrões de separação de camadas como o business delegate.

Para remover um poltergeist, exclua a classe e insira sua funcionalidade na classe invocada, possivelmente por herança ou como um mixin.

Foram propostos métodos para detectar poltergeists em código com vistas à refatoração.

Em termos de refatoração, a cura é Classe Inline. O poltergeist está muito próximo dos code smells Classe Preguiçosa e Intermediário.

Exemplo

Neste exemplo em C++, UserCreator é um poltergeist: é instanciado apenas para criar um UserManager, chamar um de seus métodos e desaparecer.

import std;

using String = std::string;

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

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

int main() {
    // Cria um poltergeist só para chamar createUser()
    UserCreator("Alice");
    UserCreator("Bob");
}

Sem o poltergeist, quem chama usa UserManager diretamente, e há uma classe a menos para ler e manter:

import std;

using String = std::string;

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

// Sem UserCreator: quem chama fala diretamente com UserManager
int main() {
    UserManager manager;
    manager.createUser("Alice");
    manager.createUser("Bob");
}

Adaptado do artigo da Wikipédia “Poltergeist (computer programming)” (revisão 1321576717), disponível sob a licença CC BY-SA 4.0; o texto foi traduzido e editado, e exemplos foram adicionados.