سؤال

أقوم بتنفيذ إطار إعلام لأحد مشاريعي. كما أريد أن تكون عامة جدا، يمكن للمستخدم استخدام العديد من طبقات النقل، بحيث لا يحتاج حقا إلى تهتم باستخدام طريقة تسليم واحدة (دعونا نقول WCF) أو آخر (على سبيل المثال ActiveMQ). واجهة المستخدم يمكن للمستخدم بالطبع مستقلة عن طريقة التسليم (WCF أو ActiveMQ). ومع ذلك، فإن الطبقتين (المستهلك والمنتج) ينفذ المفردات، لذلك يستخدمون بالفعل منشئين افتراضيون (معنى، لا معلمات). مشكلتي هي أنني أود الحصول على معلمة واحدة، طريقة التسليم التي يرغب المستخدم في استخدامها. ولكن بقدر ما أعرف، استخدم Singleton فقط منشئين آخرين؟ وهو أمر طبيعي، حيث يجب أن يكون هناك أي نقطة باستخدام singletons مع المعلمات. إذن، ما هي خياراتي هنا؟ عدم إنشاء singleton؟ إنشاء طريقة لتعيين طريقة التسليم؟

شكرا جزيلا لك على مساعدتك،

سيباستيان

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

المحلول

يمكنك بالتأكيد أن يكون لديك معلمات مع Singletons، باستثناء بدلا من اجتياز المعلمة في منشئ، فأنت تمر بطريقة GetInstance (). يجب أن يكون منشئك التجاوزي خاص بالطبع لتنفيذ Singleton الحقيقي. مثالي مكتوب في جافا ولكن ينطبق على C # كذلك.

مثال:

Singleton s = Singleton.getInstance(42);

في رمز Singleton:

private Singleton() {

}

private Singleton(int num) {
   //set num
}

public getInstance(int num) {
  //singleton code (calls the private non-default constructor if an object 
  //does not already exist) 
}

نصائح أخرى

هناك بعض أطر حقن التبعية مثل spring.net والتي قد تساعدك. يمكنك اجتياز معلمة فعالة في ملف التكوين لبناء Singletons الخاص بك.

الرابط إلى مثال إطار الربيع

قد أقترح أنه إذا كان لديك سلوكتان مختلفان مطلوبان من Singleton الذي قد ترغب في تصنيفه. بهذه الطريقة تحصل على السلوك الذي تريده عن طريق استدعاء Singleton من سلوك الفصل الذي تريده.

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

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

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

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

public void Init(/*parameters*/)
{
        if (_isInitialized)
        {
            throw new InvalidOperationException("Component is already initialized!");
        }
        //do your work here
}

سيتم إلقاء أي حق الوصول آخر إلى مثيل Singleton (Properties، SET، مكالمات الأسلوب) استثناء عملية غير صالح يخبر أنه لم يتم تهيئة الكائن.

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

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