对象树与组合模式的关系
Qt 的对象树机制是组合模式的一种实现,它使用了组合模式的思想来管理对象的父子关系。在 Qt 中,每个对象都可以有一个父对象,也可以有多个子对象。当一个对象的父对象被销毁时,它的子对象也会被销毁。这种父子关系的管理方式就是组合模式的一种实现方式。
使用 Qt 的对象树机制可以非常方便地实现组合模式,我们只需要在创建对象时,将其父对象作为构造函数的一个参数传递进去,就可以自动建立父子关系。在销毁对象时,我们只需要销毁根对象,就可以自动销毁其所有的子对象。这种自动管理父子关系的方式,不仅可以让代码更简洁,而且可以避免出现内存泄漏等问题。
组合模式UML类图程序示例
#include <QObject>
#include <QDebug>
// 抽象组件类
class Component : public QObject {
Q_OBJECT
public:
explicit Component(QObject *parent = nullptr) : QObject(parent) {}
virtual void operation() = 0;
};
// 叶子节点类
class Leaf : public Component {
public:
explicit Leaf(QObject *parent = nullptr) : Component(parent) {}
void operation() override { qDebug() << "Leaf operation."; }
};
// 容器节点类
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,直接给出一个程序示例。可以看到,这里并没有实现UML类图中说到的add
和remove
方法,因为Qt已经内部帮你实现了。在构造函数中,将父对象传入,相当于就是调用了add
方法,将自身设置为子节点。
注释块中,可以看到子节点调用了setParent
方法,去设置父节点。这和标准的组合模式中的父节点调用add
方法,将子节点加入到子节点列表,实际上是一样的。如果将nullptr传入setParent
方法,相当于取消父子节点关系,其实和标准的组合模式中的remove
方法是一样的。在这里,我们不需要显式的调用setParent
方法,因为在上面的构造函数中已经传入了各自的父节点,因此可以注释掉。
QObject
中的children
方法,可以获取所有的子对象(子节点)。程序示例中,operation
方法获取了所有的子对象,并调用子对象的operation
方法。子对象中的operation
方法一样会进行这个过程,不断传递直到最终的叶子对象(没有子对象的节点)。当QObject销毁时,其实也会发生类似的过程,从而让所有的子对象都销毁,实现自动的内存管理。
总结
其实没什么好说的,如果熟悉Qt开发,就会觉得本文讲的东西太肤浅了。确实,设计模式就是在日常的开发中总结和凝练出来的套路,对于有经验的程序员来说,虽然不一定知道其概念,但是已经在日常开发看到甚至已经主动的去使用了。不过系统的定义好这些设计模式的具体概念,能够让我们从更宏观的层面认识设计模式,提高架构能力。退一万步,至少能提高程序员之间的沟通效率,还是很有裨益的。
网友评论