سؤال

واحدة من المكتبات التي نستخدمها لمنتجنا يستخدم Singleton للوصول إليها. أنا متأكد من أنه تم تنفيذه كحل ثابت (ليس مصدر مفتوح). يعمل هذا جيدا لتطبيق مستند واحد، ولكن قد يكون تطبيقنا أكثر من مستند واحد محمل. أفترض أن الوصول إلى المثيل مكتوب شيئا مثل هذا:

Instance* getInstance() {
    static Instance* inst = new Instance();
    return inst;
}

في حالات مثل هذا، هل هناك طريقة لإنشاء أكثر صريحة أكثر من مثيل واحد؟ الشيء الوحيد الذي يمكنني التفكير فيه هو أن يكون لديك أكثر من عملية واستخدام نوع من IPC لربط كل شيء معا. لا أستطيع التفكير في أي شيء أقل تتبع.

لقد طلبت من البائع لتنفيذ نوع من الرمز من الجلسة حتى أتمكن من الحصول على العديد من الحالات المتزامنة، لكنها كبيرة ونحن صغيرة.

كوري

يحرر:

  • الجهاز هو آلة ويندوز
  • الثابت العالمي هو أساسا مصنع كبير. أريد رمزية جلسة من نوع من نوع ما حتى أقول بسهولة "إطلاق جميع الموارد من هذه الجلسة" (لا توجد طريقة لإعادة تهيئة الإحصاء العالمي الذي أعرفه)

بدلا من تجربة بعض الشناانيجينج المراوغة للحصول على ما أريده، سأرتدي كل شيء بأكمله مع صفي الخاص وإضافة مفتاح جلسة إلى كل Getter. داخليا، سأظل تتبع ما تم تخصيصه أضف طريقة الإصدار الخاصة بي لإعادة الموارد. هذا غير متخصص للكثير من الأسباب، لكنني لا أستطيع التفكير في فكرة أفضل.

شكرا للجميع للحصول على ملاحظات كبيرة.

هل كانت مفيدة؟

المحلول

الشيء الوحيد الذي يمكنني التفكير فيه هو الطبقة الفرعية إذا كنت محظوظا بما يكفي للحصول على فئة Singleton المعرفة مثل:

class Document {
public:
    static Document* getInstance() {
        static Document inst;
        return &inst;
    }
    virtual ~Document();
protected:
    Document();
private:
    struct Impl;
    Impl *pImpl;
};

إذا استطعت تصنيفه، فسيتم الوصول إلى الفئة الفرعية الوصول إلى المنشئ، ثم يمكنك إنشاء لا يمكن Subclass مثل:

class MyDocument: public Document {
public:
    MyDocument(): Document() {
    }
};

قد لا يكون هذا آمنا تماما لأن المنفذ قد يكون قد جعل بعض الافتراضات سيئة. لكنها فكرة أو بعض النهج الذي قد يكون لديه بعض فرصة العمل. مع أي حظ قد يكون البائع قابلة لهذا الخيار إذا ذكرت ذلك ... حظا سعيدا.

نصائح أخرى

حتى لو كنت قادرا على حل هذه المسألة بالذات أثناء وجود كل شيء يحدث في Proc، سأكون قلقا من أن هذه القضية المفروغة هي مجرد غيض من فيض. من الواضح أن المكتبة لم تكن مصممة لسيناريو الخاص بك.

عزل كل حمولة من DLL في عملية خاصة به أصوات الحق وغير الموقت بالنسبة لي، رغم ذلك بالطبع يمكن أن تكون مكلفة بالنسبة لك.

لا أستطيع أن أرى عيبا في التفكير لسوء الحظ. لقد اتخذ البائع قرارا، وأنت ملزم به. لقد قرر مثيل واحد لكل عملية، لذلك إذا كنت تريد حالات متعددة يجب أن يكون لديك عمليات متعددة مع كل ما يستطير.

بالطبع إذا افترضت أن قراره بتقييده تعسفي، وأنه لا يوجد سبب وجيه لذلك، فيمكنك محاولة الاختراق حولها. الطريقة التي يجب البدء بها في هذا المسار هو القيام ببعض التفكيك / التجمع يخطو في مصحح الأخطاء. إذا كنت تستطيع تأكيد أن مصنع مثيله يعمل تماما كما قد انتهيت أعلاه، فلا يمكن أن تشك في الاختراق معا بديلا يسمح بإنشاء مثيلات متعددة.

ولكن بالطبع المخاطر الكفأة مع هذا النهج هو أن كل سطر من التعليمات البرمجية في كود البائع يعتمد على قراره أن يكون لديك مثيل واحد هو وقت واحد على استعداد لتفجير في وجهك. هذا الكود غير مرئي لك. هل أنت مستعد للمراهنة هناك صفر هذه الخطوط؟ أعرف ما يقوله كلينت إيستوود في موقف مثل هذا؛ "هل تشعر أنك محظوظ الشرير، حسنا هل تفعل يا؟" :-)

لا توجد طرق أنيقة للحصول على مثيلات متعددة من كائن Singleton في مساحة برنامج واحدة - ولكن هذا عن قصد. بشكل عام، تستخدم فقط Singleton في القضية حيث يكون من غير المرغوب فيه أن يكون لديك مثيلات متعددة. إذا قام البائع بتنفيذ منتجها باستخدام Singleton، فقد يكون هناك أسباب وجيهة لاختيار.

ربما، إذا وصفت مشكلتك بمزيد من التفصيل، فقد تكون هناك طرق أخرى ممكنة. من الصعب القول، على أساس المعلومات المقدمة. ماذا يفعل كائن Singleton؟ لماذا تحتاج إلى حالات متعددة منه؟

باستثناء الأشياء النصية التي اقترحتها، فإن أفضل اختراق يمكنني التوصل إليه هو نسخ DLL إلى ملف جديد وتحميل DLL الجديد يدويا واستيراد جميع الوظائف التي تستخدمها لكل مثيل تقوم بإنشائه.

نأمل أن هذا يعني أن المتغيرات الثابتة لن تعزز بين الحالات المختلفة لأنها ليست تقنيا في نفس DLL. ومع ذلك، هناك الكثير من الأشياء السيئة مع هذا الحل، مثل جميع التعليمات البرمجية في DLL التي يتم استنساخها لكل إصدار ولن تتمكن من استخدام مكتبة الاستيراد، ولكن عليك تحميل DLL واستيراد جميع الوظائف يدويا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top