شعار ConstructiCat
CodeBust.
تصفح القسم ▾

الشبح.

الشبح (poltergeist) كلاس قصيرة العمر وعديمة الحالة لا توجد إلا لاستدعاء دوال كلاس أخرى، فتضيف وسيطاً دون أن تضيف أي سلوك.

في برمجة الكمبيوتر، الشبح (poltergeist) كائن قصير العمر، عديم الحالة عادةً، يُستخدم لتنفيذ التهيئة أو لاستدعاء دوال في كلاس أخرى أكثر ديمومة. ويُعدّ نمطاً مضاداً (anti-pattern). صاغ المصطلح مايكل أكرويد في مؤتمر Object World West عام 1996: فكما يظهر الشبح ويختفي بشكل غامض، يظهر هذا الكائن ويختفي. ونتيجة لذلك يصبح الكود أصعب صيانةً وتُهدر الموارد دون فائدة. والسبب المعتاد لهذا النمط المضاد هو سوء تصميم الكائنات.

غالباً ما يمكن التعرف على كائن الشبح (poltergeist) من اسمه؛ حيث يشتمل اسمه عادةً على كلمات مثل "Manager"، أو "Controller"، أو "Supervisor"، أو "StartProcess"، إلخ.

أحياناً، يتم إنشاء فئات الشبح لأن المبرمج توقع الحاجة إلى بنية أكثر تعقيداً. على سبيل المثال، ينشأ الشبح إذا كانت الطريقة (method) نفسها تعمل كـ عميل (client) ومستدعي (invoker) في نمط الأمر (command pattern)، وتوقع المبرمج فصل المرحلتين. ومع ذلك، قد لا تتحقق هذه البنية الأكثر تعقيداً على الإطلاق.

لا ينبغي خلط كائنات الشبح مع الكائنات طويلة العمر التي تحمل حالة في نمط مثل نموذج - عرض - متحكم (MVC)، أو الأنماط التي تفصل بين الطبقات مثل نمط مندوب الأعمال (business delegate pattern).

لإزالة كائن الشبح، احذف الفئة (class) وأدرج وظائفها في الفئة المستدعاة، وربما يتم ذلك عن طريق الوراثة (inheritance) أو كـ مزيج (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؛ تمت ترجمة النص وتحريره وإضافة أمثلة.