سؤال

لدي كائن شخص به مُنشئان - أحدهما يأخذ int (personId)، والآخر سلسلة (logonName).أرغب في مُنشئ آخر يأخذ سلسلة (رقم الشارة).أعلم أنه لا يمكن القيام بذلك، ولكن يبدو أنه قد يكون موقفًا شائعًا.هل هناك طريقة رشيقة للتعامل مع هذا؟أفترض أن هذا سينطبق على أي طريقة مثقلة.شفرة:

public class Person
{
    public Person() {}

    public Person(int personId)
    {
        this.Load(personId);
    }

    public Person(string logonName)
    {
        this.Load(logonName);
    }

    public Person(string badgeNumber)
    {
        //load logic here...
    }

...إلخ.

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

المحلول

قد تفكر في استخدام أنواع مخصصة.

على سبيل المثال، قم بإنشاء فئات LogonName وBadgeNumber.

ثم تبدو إعلانات الوظائف الخاصة بك...

public Person(LogonName ln)
{
    this.Load(ln.ToString());
}

public Person(BadgeNumber bn)
{
    //load logic here...
}

قد يمنحك هذا الحل مكانًا جيدًا للاحتفاظ بمنطق العمل الذي يحكم تنسيق هذه السلاسل واستخدامها.

نصائح أخرى

ربما يمكنك استخدام أساليب المصنع بدلاً من ذلك؟

public static Person fromId(int id) {
    Person p = new Person();
    p.Load(id);
    return p;
}
public static Person fromLogonName(string logonName) {
    Person p = new Person();
    p.Load(logonName);
    return p;
}
public static Person fromBadgeNumber(string badgeNumber) {
    Person p = new Person();
    // load logic
    return p;
}
private Person() {}

أمامك أربعة خيارات يمكنني التفكير فيها، ثلاثة منها تم ذكرها من قبل آخرين:

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

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

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

  4. قم بإضافة معلمة وهمية غير مستخدمة للتمييز بين التحميلين الزائدين.على سبيل المثالتك أ bool على الطريقة.يتم اتباع هذا النهج من قبل المكتبة القياسية في أماكن قليلة، على سبيل المثال. std::nothrow هي معلمة وهمية ل operator new.عيوب هذا النهج هي أنه قبيح وأنه لا يمكن قياسه.

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

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

ستكون أساليب المصنع خيارًا إذا كان لديك كود يستخدم المواد الخام بكثافة badge/logonName سلاسل، ولكن لا تستخدم بكثرة Person فصل.

إذا كنت تستخدم C#3.0، يمكنك استخدام مُهيئات الكائنات:

public Person()
{
}

public string Logon { get; set; }
public string Badge { get; set; }

يمكنك استدعاء المنشئ مثل هذا:

var p1 = new Person { Logon = "Steve" };
var p2 = new Person { Badge = "123" };

لا.

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

هذا لن ينجح.قد تفكر في إنشاء فئة تسمى BadgeNumber تقوم بتغليف سلسلة لتجنب هذا الغموض.

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

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

إما ذلك، أو التصويت لصالح نمط المصنع..

يمكنك استخدام طريقة المصنع الثابتة:

public static Person fromLogon(String logon) { return new Person(logon, null); }
public static Person fromBadge(String badge) { return new Person(null, badge); }

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

الشيء الوحيد الذي يمكنني التفكير فيه للتعامل مع ما تريد القيام به هو أن يكون لديك معلمات، واحدة تصف نوع المعلمة (تعداد مع LogonName، BadgeNumer، وما إلى ذلك) والثاني هو القيمة المعلمة.

يمكنك التبديل إلى نمط نمط المصنع.

public class Person {

  private Person() {}

  public static PersonFromID(int personId)
  {
    Person p = new Person().
    person.Load(personID);

    return p;
    this.Load(personId);
  }

  public static PersonFromID(string name)
  {
    Person p = new Person().
    person.LoadFromName(name);

    return p;
  }

  ...
}

أو، كما هو مقترح، استخدم أنواعًا مخصصة.يمكنك أيضًا اختراق شيء ما باستخدام الأدوية العامة، لكنني لا أوصي به لسهولة القراءة.

ماذا عن ...

public Person(int personId)
{
    this.Load(personId);
}

public Person(string logonName)
{
    this.Load(logonName);
}

public Person(Object badgeNumber)
{
    //load logic here...
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top