---
title: "Poltergeist (computer programming)"
type: "antipattern"
slug: "poltergeist"
url: "http://localhost:3000/en/antipatterns/poltergeist.md"
description: "Inappropriate short-lived object"
---
# Poltergeist (computer programming)

> Inappropriate short-lived object

In [computer programming](https://en.wikipedia.org/wiki/Computer%5Fprogramming "Computer programming"), a **poltergeist** (or **gypsy wagon**) is a short-lived, typically [stateless](https://en.wikipedia.org/wiki/State%5F%28computer%5Fscience%29 "State (computer science)") object used to perform initialization or to invoke methods in another, more permanent class. It is considered an [anti-pattern](https://en.wikipedia.org/wiki/Anti-pattern "Anti-pattern"). The original definition is by Michael Akroyd at the 1996 Object World West Conference:

> As a [gypsy wagon](https://en.wikipedia.org/wiki/Vardo%5F%28Romani%5Fwagon%29 "Vardo (Romani wagon)") or a [poltergeist](https://en.wikipedia.org/wiki/Poltergeist "Poltergeist") appears and disappears mysteriously, so does this short lived object. As a consequence the code is more difficult to maintain and there is unnecessary resource waste. The typical cause for this anti-pattern is poor object design.

A poltergeist can often be identified by its name; they often include words such as "Manager", "Controller", "Supervisor", "StartProcess", etc. in the name.

Sometimes, poltergeist classes are created because the [programmer](https://en.wikipedia.org/wiki/Programmer "Programmer") anticipated the need for a more complex architecture. For example, a poltergeist arises if the same method acts as both the _client_ and _invoker_ in a [command pattern](https://en.wikipedia.org/wiki/Command%5Fpattern "Command pattern"), and the programmer anticipates separating the two phases. However, this more complex architecture may actually never materialize.

Poltergeists should not be confused with long-lived, state-bearing objects of a [pattern](https://en.wikipedia.org/wiki/Software%5Fdesign%5Fpattern "Software design pattern") such as [model–view–controller](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller "Model–view–controller"), or tier-separating patterns such as [business delegate pattern](https://en.wikipedia.org/wiki/Business%5Fdelegate%5Fpattern "Business delegate pattern").

To remove a poltergeist, delete the class and insert its functionality in the invoked class, possibly by [inheritance](https://en.wikipedia.org/wiki/Inheritance%5F%28object-oriented%5Fprogramming%29 "Inheritance (object-oriented programming)") or as a [mixin](https://en.wikipedia.org/wiki/Mixin "Mixin").

There have been proposed methods in detecting poltergeists in code for refactoring.

## Example

This `Poltergeist` class in this [C++](https://en.wikipedia.org/wiki/C%2B%2B "C++") example can be seen as a "poltergeist object", due to not adding additional functionality or encapsulation and only increasing complexity with unnecessary abstraction.

import std;

using String = std::string;

// Poltergeist class that just holds a pointer, but adds no meaningful behavior
class Poltergeist {
private:
    String* s; // pointer to string, but the class itself doesn't do anything useful
public:
    explicit Poltergeist(String* s):
        s{s} {}

    ~Poltergeist() {
        delete s;
    }

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

    // No additional behavior or meaningful functionality
};

int main() {
    // Create a Poltergeist object that just holds a pointer to the string
    Poltergeist p(new String("Hello, world!"));

    // Just passes the data around without adding value
    std::println(*p.get());

    return 0;
}

This could instead be more appropriately done using a [smart pointer](https://en.wikipedia.org/wiki/Smart%5Fpointer "Smart pointer").

import std;

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

// Use smart pointers directly to manage memory
UniquePtr<String> s = std::make_unique<String>("Hello, World!");
std::println(*s);

Another example of a poltergeist/gypsy wagon object, is the following, where `UserCreator` is instantiated just to perform some basic actions.

import std;

using String = std::string;

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

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

int main() {
    // Creating a poltergeist just to call createUser()
    UserCreator("Alice");
    UserCreator("Bob");
}

This could be more appropriately done like so, avoiding any poltergeist class entirely:

// Avoid the UserCreator poltergeist entirely
int main() {
    UserManager manager;
    manager.createUser("Alice");
    manager.createUser("Bob");
}
