سؤال

لدي فئة أساسية ترثها فئة الفئات الفرعية المشتقة منها، وهي تحمل الوظائف الأساسية التي يجب أن تكون هي نفسها في جميع الفئات المشتقة:

class Basic {
public:
    Run() {
        int input = something->getsomething();
        switch(input)
        {
            /* Basic functionality */
            case 1:
                doA();
                break;
            case 2:
                doB();
                break;
            case 5:
                Foo();
                break;
        }
    }
};

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

class Basic {
protected:
    virtual void DoSomethingElse();
public:
    Run() {
        int input = something->getsomething();
        switch(input)
        {
            /* Basic functionality */
            ...

            case 6:
                DoSomethingElse();
        }
    }
};


class Derived : public Basic {
protected:
    void DoSomethingElse() { ... }
}

ولكن هذا يعني عند تغيير الوظائف في أي فئة مشتقة، سيتعين علي تحرير فئة أساسية لتعكس تلك التغييرات.

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

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

المحلول

قد تجد مفيدا للقراءة سلسلة من نمط المسؤولية وإعادة التفكير في الحل الخاص بك بهذه الطريقة.

كما يمكنك إعلان "Dorun" كطريقة محمية واتصل بها في الحالة الافتراضية الأساسية.

default:
   doRun(input);

وتحديد دورون في الفصول المشتقة.

وهذا ما يسمى نموذج طريقة القالب

نصائح أخرى

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

الطريقة العادية للتعامل مع هذا هي استخدام مصنع. في مخطط:

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

الآن لمزيد من نقاط المكافأة:

  • قم بإنشاء مخطط reghists classes مع المصنع - ستحتاج إلى تحديد المدخلات ونوع الفصل للتعامل معه

الآن عندما تأتي الحاجة إلى إدخال جديد، فإنك تستمد فئة جديدة وتسجيلها مع المصنع. الحاجة إلى بيان تبديل يختفي.

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

كولين

ولكن هذا يعني عند تغيير الوظائف في أي فئة مشتقة، سيتعين علي تحرير فئة أساسية لتعكس تلك التغييرات.

لماذا هذا صحيح؟

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

حل بسيط:

class Basic {
  public:
    void Run() {
      const int input = ...
      if (!(BaseProcess(input) || Process(input))) ...
    }

    vitual bool Process(int input) { return false; }

    bool BaseProcess(int input) {
      switch(input) {
    ...
        default: return false;
      }
      return true;
    }
...

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

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