على أنماط التصميم:متى يجب استخدام المفرد?[مغلقة]

StackOverflow https://stackoverflow.com/questions/228164

  •  03-07-2019
  •  | 
  •  

سؤال

الممجد العالمي المتغير يصبح تبجحت الدرجة العالمية.يقول البعض كسر تصميم وجوه المنحى.

أعطني سيناريوهات غير جيدة القديم المسجل حيث أنه من المنطقي استخدام المفرد.

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

المحلول

في بحثي عن الحقيقة اكتشفت أن هناك في الواقع عدد قليل جدا من "مقبول" أسباب استخدام المفرد.

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

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

أنا متأكد من أن هناك أسباب وجيهة أخرى كذلك.أليكس ميلر،"أنماط أكره"يتحدث من خدمة تحديد المواقع من جانب العميل واجهة المستخدم هو أيضا ربما يكون "مقبولا" الخيارات.

اقرأ المزيد في المفرد أنا أحبك ولكن كنت جلب لي أسفل.

نصائح أخرى

المفرد المرشح يجب تلبية ثلاثة شروط:

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

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

على سبيل المثال ، printer spooler من غير المرجح أن يسمى من أكثر من مكان واحد (قائمة الطباعة), بحيث يمكنك استخدام mutexes لحل الوصول المتزامن المشكلة.

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

وملفات التكوين القراءة التي ينبغي قراءة فقط في وقت بدء التشغيل والتغليف لهم في المفرد.

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

وأو اتصال قاعدة بيانات أو مدير الملفات وغيرها.

وقراءة سنغلتونس فقط تخزين بعض الدول العالمية (لغة المستخدم، ومساعدة أسم دليل، مسار التطبيق) معقولة. أن يكون متأن من استخدام الأوراق الوحيدة للسيطرة على منطق الأعمال - واحدة ينتهي دائما تقريبا حتى يتم متعددة

إدارة اتصال (أو مجموعة من الاتصالات) إلى قاعدة البيانات.

وأود أن استخدامه أيضا لاسترداد وتخزين المعلومات في ملفات التكوين الخارجية.

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

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

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

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

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

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

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

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

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

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

وكما قال الجميع، مورد مشترك - على وجه التحديد وهو الأمر الذي لا يمكن التعامل مع الوصول المتزامن

وأحد الأمثلة المحددة التي رأيتها، هو الكاتب لوسين مؤشر البحث.

والموارد المشتركة. خصوصا في PHP، فئة قاعدة البيانات، فئة قالب، وفئة مستودع متغير العالمية. جميعا أن تكون مشتركة من قبل جميع وحدات / الفئات التي يتم استخدامها في جميع أنحاء التعليمات البرمجية.

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

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

وA المفرد مستودع المتغير العالمي يتيح لك ومستودع متغير عالمي وموثوق بها، ويمكن استخدامها بسهولة. فإنه يرتب تصل الشفرة الكثير كبير. تخيل بعد كل قيم التكوين في مجموعة في المفرد مثل:

و$gb->config['hostname']

وأو وجود جميع القيم لغة في مجموعة مثل:

و$gb->lang['ENTER_USER']

في نهاية تشغيل التعليمات البرمجية للصفحة، وتحصل، ويقول، الآن ناضجة:

و$template

وسينغلتون، عن المفردة $gb الذي يحتوي على مجموعة لانج لاستبدال في ذلك، وإخراج كافة محملة وجاهزة. كنت للتو استبدالها في المفاتيح التي هي الآن موجودة في قيمة الصفحة ناضجة الكائن القالب، ثم خدمتها إلى المستخدم.

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

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

ويمكنك أيضا جعل خلاصة مصنع عن المفردة.

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

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

وأنا استخدامها لكائن التغليف معلمات سطر الأوامر عند التعامل مع وحدات للتوصيل. البرنامج الرئيسي لا يعرف ما هي معلمات سطر الأوامر لوحدات التي يتم تحميلها (ولا دائما حتى تعرف ما يجري تحميل وحدات). على سبيل المثال، والأحمال الرئيسية A، والتي لا تحتاج إلى أي المعلمات نفسه (لماذا ينبغي أن تأخذ مبلغ إضافي مؤشر / مرجع / أيا كان، ولست متأكدا - يبدو التلوث)، ثم تحميل وحدات X، Y، Z. واثنين من هذه، ويقول X و Z، الحاجة (أو قبول) المعلمات، ولذلك ندعو مرة أخرى إلى المفرد سطر الأوامر ليقولوا ذلك ما المعلمات لقبول، وفي وقت التشغيل يسمونه العودة إلى معرفة ما إذا كان المستخدم فعليا وتحديد أي منهم.

في نواح كثيرة، عن المفردة للتعامل مع المعلمات CGI ستعمل بالمثل إذا كنت تستخدم فقط عملية واحدة في الاستعلام (mod_ أخرى * طرق لا تفعل هذا، لذلك تريد ان تكون سيئة هناك - وبالتالي فإن الحجة التي تقول يجب عدم استخدام الأوراق الوحيدة في العالم mod_cgi في حال كنت المنفذ إلى mod_perl أو أيا كان العالم).

ومثال مع رمز، ربما.

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

http://www.edmundkirwan.com/servlet/fractal /cs1/frac-cs40.html

وإد.

1 - تعليق على الجواب الأول:

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

2 - أحاول أن لا إنشاء المفرد باليد. أنا فقط إنشاء كائن بسيط مع المنشئات التي تسمح لي لحقن المتعاونين في وجوه. إذا كنت بحاجة إلى المفرد، فما استقاموا لكم فاستقيموا استخدام إطار التبعية inyection (Spring.NET والوحدة ل.NET، الربيع للجافا)، أو بعض الدول الأخرى.

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