對象樹與組合模式的關系
Qt 的對象樹機制是組合模式的一種實現(xiàn)崔兴,它使用了組合模式的思想來管理對象的父子關系哄褒。在 Qt 中,每個對象都可以有一個父對象棺禾,也可以有多個子對象。當一個對象的父對象被銷毀時峭跳,它的子對象也會被銷毀膘婶。這種父子關系的管理方式就是組合模式的一種實現(xiàn)方式。
使用 Qt 的對象樹機制可以非常方便地實現(xiàn)組合模式蛀醉,我們只需要在創(chuàng)建對象時悬襟,將其父對象作為構(gòu)造函數(shù)的一個參數(shù)傳遞進去,就可以自動建立父子關系拯刁。在銷毀對象時脊岳,我們只需要銷毀根對象,就可以自動銷毀其所有的子對象垛玻。這種自動管理父子關系的方式割捅,不僅可以讓代碼更簡潔,而且可以避免出現(xiàn)內(nèi)存泄漏等問題帚桩。
程序示例
#include <QObject>
#include <QDebug>
// 抽象組件類
class Component : public QObject {
Q_OBJECT
public:
explicit Component(QObject *parent = nullptr) : QObject(parent) {}
virtual void operation() = 0;
};
// 葉子節(jié)點類
class Leaf : public Component {
public:
explicit Leaf(QObject *parent = nullptr) : Component(parent) {}
void operation() override { qDebug() << "Leaf operation."; }
};
// 容器節(jié)點類
class Composite : public Component {
public:
explicit Composite(QObject *parent = nullptr) : Component(parent) {}
void operation() override {
qDebug() << "Composite operation.";
for (QObject *child : children()) {
Component *component = qobject_cast<Component*>(child);
if (component) {
component->operation();
}
}
}
};
int main() {
Composite *root = new Composite();
Composite *composite1 = new Composite(root);
Composite *composite2 = new Composite(root);
Leaf *leaf1 = new Leaf(composite1);
Leaf *leaf2 = new Leaf(composite1);
Leaf *leaf3 = new Leaf(composite2);
/*
composite1->setParent(root);
composite2->setParent(root);
leaf1->setParent(composite1);
leaf2->setParent(composite1);
leaf3->setParent(composite2);
*/
root->operation();
delete root;
return 0;
}
不多bb亿驾,直接給出一個程序示例≌撕浚可以看到莫瞬,這里并沒有實現(xiàn)UML類圖中說到的add
和remove
方法儡蔓,因為Qt已經(jīng)內(nèi)部幫你實現(xiàn)了。在構(gòu)造函數(shù)中疼邀,將父對象傳入喂江,相當于就是調(diào)用了add
方法,將自身設置為子節(jié)點旁振。
注釋塊中获询,可以看到子節(jié)點調(diào)用了setParent
方法,去設置父節(jié)點拐袜。這和標準的組合模式中的父節(jié)點調(diào)用add
方法筐付,將子節(jié)點加入到子節(jié)點列表,實際上是一樣的阻肿。如果將nullptr傳入setParent
方法,相當于取消父子節(jié)點關系沮尿,其實和標準的組合模式中的remove
方法是一樣的丛塌。在這里,我們不需要顯式的調(diào)用setParent
方法畜疾,因為在上面的構(gòu)造函數(shù)中已經(jīng)傳入了各自的父節(jié)點赴邻,因此可以注釋掉。
QObject
中的children
方法啡捶,可以獲取所有的子對象(子節(jié)點)姥敛。程序示例中,operation
方法獲取了所有的子對象瞎暑,并調(diào)用子對象的operation
方法彤敛。子對象中的operation
方法一樣會進行這個過程,不斷傳遞直到最終的葉子對象(沒有子對象的節(jié)點)了赌。當QObject銷毀時墨榄,其實也會發(fā)生類似的過程,從而讓所有的子對象都銷毀勿她,實現(xiàn)自動的內(nèi)存管理袄秩。
總結(jié)
其實沒什么好說的,如果熟悉Qt開發(fā)逢并,就會覺得本文講的東西太膚淺了之剧。確實,設計模式就是在日常的開發(fā)中總結(jié)和凝練出來的套路砍聊,對于有經(jīng)驗的程序員來說背稼,雖然不一定知道其概念,但是已經(jīng)在日常開發(fā)看到甚至已經(jīng)主動的去使用了辩恼。不過系統(tǒng)的定義好這些設計模式的具體概念雇庙,能夠讓我們從更宏觀的層面認識設計模式谓形,提高架構(gòu)能力。退一萬步疆前,至少能提高程序員之間的溝通效率寒跳,還是很有裨益的。