Ska*_*One 0 c++ design-patterns
想象一下,有一个叫做Node
可以容纳多个父母和多个孩子的班级:
class Node {
public:
Node();
virtual void addParent(Node *parent);
virtual void addChild(Node *child);
private:
vector<Node*> m_parents;
vector<Node*> m_children;
};
Run Code Online (Sandbox Code Playgroud)
问题是每次向节点添加父节点时,m_parents
必须更新节点并且必须更新父节点m_children
; 这会产生无限循环.
void Node::addParent(Node *parent)
{
if (m_parents.lacks(parent)) { // supposing such method exists
m_parents.push_back(parent);
}
parent->addChild(this);
}
void Node::addChild(Node *child)
{
if (m_children.lacks(child)) {
m_children.push_back(child);
}
child->addParent(this);
}
Run Code Online (Sandbox Code Playgroud)
如你所见,这并不好.我设法通过添加四种方法来解决这个问题而不是两种方法,但感觉有点愚蠢.另外两种方法都是声明的private
,protected
因此不能被其他方法调用.这是原始addParent
和新方法,称为rawAddChild
:
void Node::addParent(Node *parent)
{
if (m_parents.lacks(parent)) {
m_parents.push_back(parent);
}
parent->rawAddChild(this);
}
void Node::rawAddChild(Node *child)
{
if (m_children.lacks(child)) {
m_children.push_back(child);
}
// Doesn't call for parent's method
}
Run Code Online (Sandbox Code Playgroud)
对于addChild()
和,这显然是相同的rawAddParent()
.
然而,这并不觉得自己是一个妥善的解决办法,它肯定不明确的"外人"为什么有addChild
和rawAddChild
方法.我的逻辑是否存在问题,如果是,我该如何解决这个问题呢?或者我的解决方案已经很好了?
我建议只在两种方法中的一种方法中进行实际操作:
void Node::addParent(Node *parent)
{
if (m_parents.lacks(parent)) {
m_parents.push_back(parent);
}
if (parent->m_children.lacks(this)) {
parent->m_children.push_back(this);
}
}
void Node::addChild(Node *child)
{
child->addParent(this);
}
Run Code Online (Sandbox Code Playgroud)