美文网首页
S11 组合模式

S11 组合模式

作者: 拂去尘世尘 | 来源:发表于2022-01-23 21:54 被阅读0次

    组合模式

    组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构。 -- 百度百科

    组合模式能够体现各个对象之间的层次关系,将所有对象设计为同一种类型,从而忽略组合与个体的差异,统一管理起来。

    意义

    组合模式将所有的对象统一管理,并按照树形排列起来。用户能够按照结构顺序来查询指定位置的对象属性。

    应用场景

    1. 公司的结构顺序。公司存在多个部门,部门内又存在多个小组,小组内存在多个成员。
    2. 特殊类型的文件操作。类似于Xml类型的文本类型,其内部需要实现指定节点的增、删、改、查功能。

    场景

    设计一套层次关系,实现指定位置插入、删除节点的操作。

    类图

    组合模式
    • CTree: 统一的基类,定义统一的接口Add、Remove,由子类实现添加删除具体节点操作。
    • CLeaf: 叶子类,其不再存在子组件的节点。
    • CTrunk: 枝干类,还存在子组件的节点。

    效果

    客户端接口

    //                      root
    //                  /    \     \
    //                 /      \     \
    //               branch1 branch2 leaf
    //              /   \         \
    //             /     \         \
    //        branch1_1  leaf1_1  leaf2_1
    
    int main(int argc, char *argv[])
    {
        CTrunk theRoot("root");
        CTrunk theBranch1("branch1");
        CTrunk theBranch2("branch2");
        CTrunk theBranch1_1("branch1_1");
        CLeaf  theLeaf("leaf");
        CLeaf  theLeaf1_1("leaf1_1");
        CLeaf  theLeaf2_1("leaf2_1");
    
        theBranch1.Add(&theBranch1_1);
        theBranch1.Add(&theLeaf1_1);
    
        theBranch2.Add(&theLeaf2_1);
    
        theRoot.Add(&theBranch1);
        theRoot.Add(&theBranch2);
        theRoot.Add(&theLeaf);
    
    
        theRoot.ShowAllBranch(&theRoot);
        //theRoot.ShowBranch();
        return 0;
    }
    

    输出

    branch1 branch1_1 leaf1_1 
    branch2 leaf2_1 
    leaf 
    

    具体实现

    基类接口
    定义对外接口,包括增加、删除节点接口。

    class CTree
    {
    public:
        CTree(): mParent(0), mFirstChild(0), mLastChild(0), mPrev(0), mNext(0)
        {}
        
        virtual ~CTree() 
        {}
    
        virtual CTree* Add(CTree *pNode);
    
        virtual int Remove(CTree *pNode);
    
        virtual string GetName();
    
        virtual bool IsTrunk() const;
    
        CTree *mParent;
    
        CTree *mFirstChild;
        CTree *mLastChild;
    
        CTree *mPrev;
        CTree *mNext;
    };
    

    叶子类
    叶子类无需增加子节点。

    class CLeaf 
    {
    public:
        explicit CLeaf(string Name);
    
        ~CLeaf();
    
        string GetName();
    
    private:
        string mName;
    };
    

    枝干类
    枝干类需要实现增加节点接口,通过链表将各个节点连接起来。

    class CTrunk : public CTree
    {
    public:
        explicit CTrunk(string Name);
    
        ~CTrunk();
        
        CTree* Add(CTree *pNode);
    
        int Remove(CTree *pNode);
    
        string GetName();
    
        bool IsTrunk() const;
    
        void ShowBranch();
    
        void ShowAllBranch(CTree *p);
    
    private:
        string mName;
    };
    

    枝干类增加节点。每个枝干类内部维护一套双向链表,用于维护当前类增加的节点。

    CTree* CTrunk::Add(CTree *pNode)
    {
        if (NULL == pNode) {
            return 0;
        }
    
        if (mLastChild) {
            pNode->mNext = 0;
            pNode->mPrev = mLastChild;
            mLastChild->mNext = pNode;
            mLastChild = pNode;
        }
        else {
            mFirstChild = mLastChild = pNode;
            pNode->mPrev = 0;
            pNode->mNext = 0;
        }
    
        pNode->mParent = this;
        return pNode;
    }
    

    总结

    • 组合模式,主要用于将相同类型的对象统一的按照树形方式管理起来,便于实现"增、删、改、查"的行为。类似Xml、部门管理的场景比较适合。

    • 在使用过程中,客户端需要手动创建和释放,后面更新为自动创建回收就比较完美了。

    相关文章

      网友评论

          本文标题:S11 组合模式

          本文链接:https://www.haomeiwen.com/subject/dprvhrtx.html