سؤال

متى يجب ألا تستخدم الفصل الفردي على الرغم من أنه قد يكون من المغري جدًا القيام بذلك؟سيكون من الرائع جدًا أن تكون لدينا قائمة بالحالات الأكثر شيوعًا لـ "التهاب اللوزتين" والتي يجب أن نحرص على تجنبها.

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

المحلول

لا تستخدم قطعة مفردة لشيء قد يتطور إلى مورد مضاعف.

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

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

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

نصائح أخرى

حسنًا، العزاب في معظم الأحيان يجعلون الأمور ثابتة على أي حال.إذن، إما أنك في الواقع تجعل البيانات عالمية، ونعلم جميعًا أن المتغيرات العالمية سيئة أو أنك تكتب أساليب ثابتة وهذا ليس بالأمر المهم الآن، أليس كذلك؟

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

أعلم أن الكثيرين أجابوا بـ "عندما يكون لديك أكثر من واحد"، وما إلى ذلك.

نظرًا لأن الملصق الأصلي أراد قائمة بالحالات التي لا يجب عليك فيها استخدام Singletons (بدلاً من السبب الرئيسي)، فسوف أتوافق مع:

كلما كنت تستخدمه لأنه غير مسموح لك باستخدام عالمي!

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

أنا مذنب بارتكاب جريمة كبيرة قبل بضع سنوات (لحسن الحظ أنني تعلمت الدرس منذ ذلك الحين).

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

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

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

تعتبر المفردات دائمًا فكرة سيئة وغير مجدية/زائدة عن الحاجة بشكل عام نظرًا لأنها مجرد تبسيط محدود جدًا لنمط لائق.

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

على الرغم من أنه يمكنك العثور على مكتبات DI هناك، إلا أنه يمكنك أيضًا إنشاء مكتبة أساسية بنفسك، فالأمر سهل جدًا.

أحاول الحصول على مفردة واحدة فقط - وهو انعكاس لكائن محدد موقع التحكم/الخدمة.

IService service = IoC.GetImplementationOf<IService>();

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

عندما يكون لديك تطبيقات متعددة تعمل في نفس JVM.

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

في بعض الأحيان، تفترض أنه لن يكون هناك سوى شيء واحد، ثم يتبين أنك مخطئ.

على سبيل المثال، فئة قاعدة البيانات.تفترض أنك لن تتصل إلا بقاعدة بيانات تطبيقك.

// Its our database! We'll never need another
class Database
{
};

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

كنت تفضل ذلك

Database ourDb;
Database otherDb;

من نسخ قاعدة البيانات السابقة وإجراء:

// Copy-pasted from our home-grown database.
class OtherGuysDatabase
{
};

المنحدر الزلق هنا هو أنك قد تتوقف عن التفكير في إنشاء مثيل جديد للفئات وبدلاً من ذلك تبدأ في التفكير في أنه من المقبول أن يكون لديك نوع واحد في كل مثيل.

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

ولكن لماذا لا تفعل ذلك وصول جميع اتصالاتك من خلال واجهة واحدة (أي.مدير الاتصال)؟

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