هل هناك أي بدائل مجدية صندوق جلوبل القناص المفرد النمط ؟

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

  •  03-07-2019
  •  | 
  •  

سؤال

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

هل هناك أي بدائل محددة إلى صندوق جلوبل القناص المفرد النمط ؟

على سبيل المثال, العديد من الأوقات عندما يستخدم نمط سينغلتون في الماضي ، أنا ببساطة ترغب في الحفاظ على الدولة/قيم واحد أو عدة متغيرات.الدولة/قيم المتغيرات ، ومع ذلك ، يمكن أن تكون محفوظة بين كل مثيل من فئة باستخدام متغيرات ثابتة بدلا من استخدام نمط المفرد.

ما الفكرة لديك ؟

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

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

المحلول

أليكس ميلر في "أنماط أكره"ونقلت التالية:

"عندما المفرد يبدو الجواب, أجد أنه غالبا ما يكون من الحكمة:

  1. إنشاء واجهة افتراضية تنفيذ المفرد
  2. إنشاء مثيل واحد من الافتراضي الخاص بك في "أعلى" من النظام الخاص بك.هذا قد يكون في الربيع config أو في قانون أو تعريف في مجموعة متنوعة من الطرق اعتمادا على النظام الخاص بك.
  3. تمرير مثيل واحد في كل عنصر يحتاج إليها (حقن التبعية)

نصائح أخرى

لفهم الطريقة الصحيحة ووحدانية الحل, تحتاج إلى فهم ما هو الخطأ مع وحدانية (والعالمية الدولة بشكل عام):

ووحدانية إخفاء التبعيات.

لماذا هذا مهم ؟

لأن إذا قمت بإخفاء التبعيات كنت تميل إلى تفقد المسار من كمية اقتران.

هل يمكن القول أن

void purchaseLaptop(String creditCardNumber, int price){
  CreditCardProcessor.getInstance().debit(creditCardNumber, amount);
  Cart.getInstance().addLaptop();
}

هو أبسط من

void purchaseLaptop(CreditCardProcessor creditCardProcessor, Cart cart, 
                    String creditCardNumber, int price){
  creditCardProcessor.debit(creditCardNumber, amount);
  cart.addLaptop();
}

ولكن في الثانية على الأقل API يجعل من الواضح بالضبط ما الأسلوب المتعاونين.

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

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

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

في ملخص, ماذا يجب أن تفعل ؟ كلما كائن يعتمد على آخر ، سوف تتلقى مثيل إلا من خلال منشئ (أي الكلمة في صفك).

class NeedyClass {

    private ExSingletonClass exSingleton;

    public NeedyClass(ExSingletonClass exSingleton){
        this.exSingleton = exSingleton;
    }

    // Here goes some code that uses the exSingleton object
}

ثم المصنع.

class FactoryOfNeedy {

    private ExSingletonClass exSingleton;

    public FactoryOfNeedy() {
        this.exSingleton = new ExSingletonClass();
    }

    public NeedyClass buildNeedy() {
        return new NeedyClass(this.exSingleton);
    }
}

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

آمل أن يساعد هذا.يرجى الإشارة إلى أي أخطاء.

الربيع أو أي IoC-حاوية هل معقول وظيفة جيدة في ذلك.منذ فئات يتم إنشاؤها وإدارتها خارج التطبيق نفسه ، الحاوية يمكن أن تجعل بسيطة الطبقات ووحدانية وضخها عند الحاجة.

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

لا تجنب نمط المفرد.إما أنه من المناسب استخدام أو أنه لا مناسبة و لا استخدامه.وأعتقد أن هذا هو بهذه البساطة.

ملاءمة (أو عدمه) من المفرد يعتمد على الوضع.وهو تصميم المقرر أنه يجب أن يتم عواقب هذا القرار يجب أن يكون مفهوما (وثقت).

على المفرد نمط موجود لأن هناك حالات عندما كائن واحد هو الحاجة إلى توفير مجموعة من الخدمات.

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

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

*pseudocode* currentContainer.GetServiceByObjectType(singletonType)
//Under the covers the object might be a singleton, but this is hidden to the consumer.

بدلا من عالمي واحد

*pseudocode* singletonType.Instance

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

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

رأيي هو أن إخفاء استخدام نمط المفرد كلما أمكن ذلك ، لأنه ليس من الممكن دائما تجنب ذلك ، أو مرغوب فيه.

Monostate (في وصفها روبرت C.مارتن تطوير البرمجيات رشيق) هو بديل المفرد.في هذا النمط فئة البيانات كلها ثابتة ولكن حاصل/المحددات غير ثابت.

على سبيل المثال:

public class MonoStateExample
{
    private static int x;

    public int getX()
    {
        return x;
    }

    public void setX(int xVal)
    {
        x = xVal;
    }
}

public class MonoDriver
{
    public static void main(String args[])
    {
        MonoStateExample m1 = new MonoStateExample();
        m1.setX(10);

        MonoStateExample m2 = new MonoStateExample();
        if(m1.getX() == m2.getX())
        {
            //singleton behavior
        }
    }
}

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

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

(على الرغم من أنني أزعم أن هذا هو الطريق الخطأ استخدام المفرد في المقام الأول)

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

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

استخدام عادي موضوع مصنع كائن.المصنع هو المسؤول عن الشرطة مثيل و سهل كائن التفاصيل فقط مع معلومات التكوين (يحتوي على سبيل المثال) والسلوك.

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

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

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

بالنسبة لي شخصيا а أكثر طريقة معقولة لتنفيذ شيء أن يتصرف مثل المفرد هو استخدام بالكامل الفئة ثابتة(static أعضاء أساليب ثابتة , خصائص ثابتة).معظم الوقت أنا تنفيذه في هذا الطريق (لا أستطيع أن أفكر في أي سلوك الاختلافات من نظر المستخدم)

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

إذا كان هذا هو الحال, ثم لديك المفرد.إذا كنت رمي ووحدانية في لراحتك أثناء الترميز ثم كنت حقا ينبغي أن يكون إعادة النظر في التصميم الخاص بك و أيضا إيقاف الترميز قال ووحدانية :)

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

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

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

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

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

ماذا تعني و ما هي تقنيات لتجنب ذلك ؟

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

ولكن هناك لا.أنا لم يكن لديك لتجنب المفرد النمط.فإنه ببساطة لا تنشأ.

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