Полтергейст.
Полтергейст — короткоживущий класс без состояния, который существует только для вызова методов другого класса и добавляет косвенность без поведения.
В программировании полтергейст — это короткоживущий, обычно не имеющий состояния объект, используемый для выполнения инициализации или для вызова методов в другом, более постоянном классе. Он считается антипаттерном. Термин ввёл Майкл Акройд на конференции Object World West в 1996 году: подобно полтергейсту, такой объект загадочно появляется и исчезает. Как следствие, код становится труднее сопровождать, а ресурсы расходуются впустую. Типичная причина этого антипаттерна — плохое проектирование объектов.
Полтергейст часто можно опознать по его имени; в них нередко встречаются такие слова, как «Manager», «Controller», «Supervisor», «StartProcess» и т. п.
Иногда классы-полтергейсты создаются потому, что программист предвосхищал потребность в более сложной архитектуре. Например, полтергейст возникает, если один и тот же метод выступает одновременно и клиентом, и инициатором в паттерне «Команда», и программист предполагает разделить эти две фазы. Однако такая более сложная архитектура в действительности может так и не появиться.
Полтергейсты не следует путать с долгоживущими, несущими состояние объектами паттернов, таких как модель—представление—контроллер, или паттернов, разделяющих уровни, таких как паттерн «Бизнес-делегат».
Чтобы устранить полтергейст, удалите класс и перенесите его функциональность в вызываемый класс, возможно, посредством наследования или в виде примеси (mixin).
Были предложены методы обнаружения полтергейстов в коде для целей рефакторинга.
В терминах рефакторинга лечение — это Встраивание класса. Полтергейст близок к запахам кода Ленивый класс и Посредник.
Пример
В этом примере на C++ полтергейстом является UserCreator: его экземпляр создаётся лишь для того, чтобы создать UserManager, вызвать один его метод и тут же исчезнуть.
import std;
using String = std::string;
class UserManager {
public:
void createUser(const String& name) {
std::println("User created: {}", name);
}
};
// Класс-полтергейст
class UserCreator {
public:
explicit UserCreator(const String& name) {
UserManager manager;
manager.createUser(name);
}
};
int main() {
// Создаём полтергейст только ради вызова createUser()
UserCreator("Alice");
UserCreator("Bob");
}
Без полтергейста вызывающий код работает с UserManager напрямую, и читать и сопровождать приходится на один класс меньше:
import std;
using String = std::string;
class UserManager {
public:
void createUser(const String& name) {
std::println("User created: {}", name);
}
};
// Без UserCreator: вызывающий код обращается к UserManager напрямую
int main() {
UserManager manager;
manager.createUser("Alice");
manager.createUser("Bob");
}
Адаптировано по статье Википедии “Poltergeist (computer programming)” (версия 1321576717), распространяется по лицензии CC BY-SA 4.0; текст переведён и отредактирован, добавлены примеры.