هل تستخدم الإشارات/الفتحات لتجنب التبعيات الدائرية؟

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

  •  21-12-2019
  •  | 
  •  

سؤال

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

على سبيل المثال، هذا الكود (تصميمي الحالي) ينشئ C2027:

النافذة الرئيسية:

#include "mainwindow.h"
#include "ui_mainwindow.h"

vector<Foo*> FooArray;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    scene = new QGraphicsScene(this);
    ui->graphicsView->setScene(scene);

    int viewwidth = ui->graphicsView->width();

    ...

    FooArray.push_back(new Foo(5, viewwidth, scene));
    FooArray[0]->loadBars();
}

فو:

#include "Foo.h"  //includes bar.h


vector<int> ActiveList;
vector<Bar*> BarArray;

Foo::Foo(int id, int w, QGraphicsScene* scene)
{
    this->id = id;
    this->width = w;
    this->scene = scene;
}

...

void Foo::loadBars()
{
    ...
    BarArray.resize(nitems);
    BarArray[k] = new Bar(id, k, this);
    BarArray[k]->setPos(...);
    scene->addItem(BarArray[k]);
    ...
}

void Foo::doSomething()
{
    ...
}

حاجِز:

#include "Bar.h"  //forward declares Foo; isn't executed until Foo exists. 

Bar::Bar(int setid, int num, Foo* foo)
{
    this->s = setid;
    this->n = num;
    this->owner = foo;
}

...

void Bar::someFunction()
{   
    ...
    owner->doSomething();
    ...
}
هل كانت مفيدة؟

المحلول

نعم، هذا هو بالضبط الغرض من الإشارات والفتحات.

الآن لديك Bar::someFunction() الذي يدعو Foo::doSomething()

ما يمكنك فعله بدلاً من ذلك هو:

  1. يعلن doSomething() بمثابة فتحة
  2. اجعل الشريط يصدر إشارة somethingHappened()
  3. عند إنشاء الأطفال، قم بتوصيلهم somethingHappened() إشارة إلى الوالدين doSomething() فتحة

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

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