组合模式
注:本文中使用的C++ QT框架
目录
1. 设计目的
是为了解决树型结构中,需要向客户端提供一致的操作接口,使得客户端操作忽略简单元素与复杂元素的方案。比如:在 操作XML文件时,客户端希望操作XML节点和操作文本值的接口是一样的,从而不用去关系如何设置节点或如何设置文本值。
2. UML设计
以操作xml的树型结构为例:
3. 代码实现
//XmlNodeInterface.h
#ifndef XMLNODEINTERFACE_H
#define XMLNODEINTERFACE_H
#include <QObject>
class XmlNodeInterface : public QObject
{
Q_OBJECT
public:
explicit XmlNodeInterface(QObject *parent = nullptr);
public:
//节点操作
/**
* @brief getNodeName 获取节点元素名称
* @return
*/
virtual QString getNodeName() = 0;
virtual void setNodeName(QString nodeName) = 0;
/**
* @brief getAttribute 获取该节点属性
* @return
*/
virtual QMap<QString, QString> getAttribute() = 0;
virtual void setAttribue(QMap<QString, QString> attribute) = 0;
/**
* @brief getElementValue 获取元素值
* @return
*/
virtual QVariant getElementValue() = 0;
virtual void setElementValue(QVariant elementValue) = 0;
//节点操作
/**
* @brief getNodeList 获取该节点下的所有子节点列表
* @return
*/
virtual QList< QSharedPointer<XmlNodeInterface>> getNodeList() = 0;
/**
* @brief addnewNode 添加新的节点,操作节点m_mapNode
* @param node
* @return
*/
virtual void append(QSharedPointer<XmlNodeInterface> value) = 0;
/**
* @brief pop 弹出一个节点
* @param node
* @return
*/
virtual void pop(QSharedPointer<XmlNodeInterface> value) = 0;
signals:
public slots:
};
#endif // XMLNODEINTERFACE_H
//XmlNode.h
#ifndef CHILDNODE_H
#define CHILDNODE_H
#include <QObject>
#include <QMap>
#include <QMultiMap>
#include <QSharedPointer>
#include "XmlNodeInterface.h"
#include <QVariant>
class XmlNode : public XmlNodeInterface
{
Q_OBJECT
public:
explicit XmlNode(XmlNodeInterface *parent = nullptr);
signals:
public slots:
public:
virtual QString getNodeName();
virtual void setNodeName(QString nodeName);
virtual QMap<QString, QString> getAttribute();
virtual void setAttribue(QMap<QString, QString> attribute);
virtual QVariant getElementValue();
virtual void setElementValue(QVariant elementValue);
//节点操作
virtual QList< QSharedPointer<XmlNodeInterface>> getNodeList();
virtual void append(QSharedPointer<XmlNodeInterface> value);
virtual void pop(QSharedPointer<XmlNodeInterface> value);
private:
QString m_xmlNodeName;
QMap<QString, QString> m_attribute;
QVariant m_elementValue;
QList< QSharedPointer<XmlNodeInterface>> m_listNode; ///< 可满足多元素的列表
};
#endif // CHILDNODE_H
//XmlNode.cpp
#include "XmlNode.h"
#include <QDebug>
XmlNode::XmlNode(XmlNodeInterface *parent) : XmlNodeInterface(parent)
{
}
QString XmlNode::getNodeName()
{
return m_xmlNodeName;
}
void XmlNode::setNodeName(QString nodeName)
{
m_xmlNodeName = nodeName;
}
QMap<QString, QString> XmlNode::getAttribute()
{
return m_attribute;
}
void XmlNode::setAttribue(QMap<QString, QString> attribute)
{
m_attribute = attribute;
}
QVariant XmlNode::getElementValue()
{
// if(m_elementValue.isNull())
// {
// qInfo() << "读取的元素值为空";
// }
// qInfo()<< "ChildNode::getElementValue";
return m_elementValue;
}
void XmlNode::setElementValue(QVariant elementValue)
{
qWarning() <<"节点对象设置元素值无效";
Q_UNUSED(elementValue);
// m_elementValue = elementValue;
}
QList<QSharedPointer<XmlNodeInterface> > XmlNode::getNodeList()
{
return m_listNode;
}
void XmlNode::append(QSharedPointer<XmlNodeInterface> node)
{
m_listNode.append(node);
}
void XmlNode::pop(QSharedPointer<XmlNodeInterface> value)
{
m_listNode.removeOne(value);
}
//XmlTexrtValue.h
#ifndef NODEELEMENT_H
#define NODEELEMENT_H
#include <QObject>
#include <QVariant>
#include "XmlNodeInterface.h"
class XmlTextValue : public XmlNodeInterface
{
Q_OBJECT
public:
explicit XmlTextValue(XmlNodeInterface *parent = nullptr);
public:
virtual QString getNodeName();
virtual void setNodeName(QString nodeName);
virtual QMap<QString, QString> getAttribute();
virtual void setAttribue(QMap<QString, QString> attribute);
virtual QVariant getElementValue();
virtual void setElementValue(QVariant elementValue);
//节点操作
virtual QList< QSharedPointer<XmlNodeInterface>> getNodeList();
virtual void append(QSharedPointer<XmlNodeInterface> value);
virtual void pop(QSharedPointer<XmlNodeInterface> value);
signals:
public slots:
private:
QString m_xmlNodeName;
QMap<QString, QString> m_attribute;
QVariant m_elementValue;
};
#endif // NODEELEMENT_H
//XmlTextValue.cpp
#include "XmlTextValue.h"
#include <QSharedPointer>
#include <QDebug>
XmlTextValue::XmlTextValue(XmlNodeInterface *parent) : XmlNodeInterface(parent),
m_elementValue("")
{
}
QString XmlTextValue::getNodeName()
{
return m_xmlNodeName;
}
void XmlTextValue::setNodeName(QString nodeName)
{
m_xmlNodeName = nodeName;
}
QMap<QString, QString> XmlTextValue::getAttribute()
{
return m_attribute;
}
void XmlTextValue::setAttribue(QMap<QString, QString> attribute)
{
m_attribute = attribute;
}
QVariant XmlTextValue::getElementValue()
{
if(m_elementValue.isNull())
{
qInfo() << "读取的元素值为空";
}
return m_elementValue;
}
void XmlTextValue::setElementValue(QVariant elementValue)
{
m_elementValue = elementValue;
}
QList<QSharedPointer<XmlNodeInterface> > XmlTextValue::getNodeList()
{
// qWarning() << "元素值对象无节点列表";
return QList<QSharedPointer<XmlNodeInterface>>();
}
void XmlTextValue::append(QSharedPointer<XmlNodeInterface> value)
{
qWarning() <<"元素值对象无法再去附加节点";
Q_UNUSED(value);
}
void XmlTextValue::pop(QSharedPointer<XmlNodeInterface> value)
{
qWarning() << "元素值对象无法去弹出节点指针";
Q_UNUSED(value);
}