In computer programming, a poltergeist (or gypsy wagon) is a short-lived, typically stateless object used to perform initialization or to invoke methods in another, more permanent class. It is considered an anti-pattern. The original definition is by Michael Akroyd at the 1996 Object World West Conference:[ citation needed ]
As a gypsy wagon or a 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 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, 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 such as model–view–controller, or tier-separating patterns such as business delegate pattern.
To remove a poltergeist, delete the class and insert its functionality in the invoked class, possibly by inheritance or as a mixin.
There have been proposed methods in detecting poltergeists in code for refactoring. [1]
This Poltergeist class in this C++ example can be seen as a "poltergeist object", due to not adding additional functionality or encapsulation and only increasing complexity with unnecessary abstraction.
importstd;usingString=std::string;// Poltergeist class that just holds a pointer, but adds no meaningful behaviorclassPoltergeist{private:String*s;// pointer to string, but the class itself doesn't do anything usefulpublic:explicitPoltergeist(String*s):s{s}{}~Poltergeist(){deletestr;}[[nodiscard]]Stringget()constnoexcept{returns;}// No additional behavior or meaningful functionality};intmain(){// Create a Poltergeist object that just holds a pointer to the stringPoltergeistp(newString("Hello, world!"));// Just passes the data around without adding valuestd::println(*p.get());return0;}This could instead be more appropriately done using a smart pointer.
importstd;usingString=std::string;template<typenameT>usingUniquePtr=std::unique_ptr<T>;// Use smart pointers directly to manage memoryUniquePtr<String>s=std::make_unique<String>("Hello, World!");std::println(*s);