تحتاج إلى نمط تصميم لإزالة enums و بيان التبديل في إنشاء كائن

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

سؤال

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

public abstract class Position
{
 public abstract string Name
 {
  get;
 }
}

و أقسام فرعية...

public class Defender : Position
{
 public override string Name
 {
  get { return "Defender"; }
 }
}

وهلم جرا.هذا هو كل شيء على ما يرام.

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

public static Position GetByType(Types position)
{
 switch(position)
 {
  case Types.Defender:
   return new Defender();
... and further terrible code

ما الحل هل يجب أن تبحث في ؟ وهو نمط تصميم هذا ؟

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

المحلول

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

إذا كان لديك للقيام بذلك على متوسط الحجم ، قد ترغب في النظر في تحسين الداخلية قليلا -- ستيف Ellinger اقتراح معقول واحد.أنا شخصيا أفضل استخدام IDictionary<MyEnum, Action<T>> حيث يعود العمل مثيل جديد من فئة في السؤال.

إذا كان لديك للقيام بذلك على الكبير أو شكلي الحجم ، ربما يجب أن تحقق من وراء البحار تحكم مثل structuremap أو ninject أو أيا كان الاطفال يلعبون بارد مع هذه الأيام.

نصائح أخرى

يبدو مثل نمط المصنع.

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

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

لا يوجد حقًا أي شيء أكثر أناقة يمكنك القيام به إلا إذا كنت ترغب في استخدام الانعكاس لمحاكاة ما يفعله PHP.

تتمثل إحدى طرق التعامل مع المفتاح في جعل المصنع يعلن مجموعة من الأنواع ثم استخدام التعداد كفهرس في الصفيف مثل SO:

public abstract class Position {
    public abstract string Name {
        get;
    }
}
public class Defender : Position {
    public override string Name {
        get { return "Defender"; }
    }
}
public class Attacker : Position {
    public override string Name {
        get { return "Attacker"; }
    }
}
public static class PositionFactory {
    public enum Types {
        Defender, Attacker
    }
    private static Type[] sTypes = new Type[] { typeof(Defender), typeof(Attacker)};
    public static Position GetByType(Types positionType) {
        return Activator.CreateInstance(sTypes[(Int32)positionType]) as Position;
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top