【设计模式】组合模式

组合模式(composite)主要用来解决树形层次结构对象模型。用统一的component对象屏蔽不同类型的子节点的差异。对于客户端来说都提供一个统一的接口。

典型应用场景如菜单,文件树等。

组合模式思想感觉跟递归有一些关系。将不同的items组合成一个composite,而不同的composite和叶子节点又能组合出新的composite。

看起来该模式似乎还比较简单。但是也没想到更多的场景。后面遇到再说吧。

写了个简单demo,可以描述一个文件系统:

/**
 * @file test_composite.h
 * @author itegel
 * @date 2014/04/02 10:14:25
 * @brief 
 *  
 **/

#ifndef  __TEST_COMPOSITE_H_
#define  __TEST_COMPOSITE_H_

#include <iostream>
#include <vector>
#include <string>

class Component{
    public:
        Component(){}
        virtual void Add(Component * component) = 0;
        virtual void Remove(Component * component) {
            //do nothing for test
        }
        virtual void DisplayInfo() = 0;
};

class File : public Component{
    public:
        File(const char * name, int id){
            name_ = name;
            id_ = id;
        }

        virtual void Add(Component * component){
            std::cout<<"File node cannot add sons!"<<std::endl;
            //throw exception or do some exception handling here
        }

        virtual void DisplayInfo(){
            std::cout<<name_<<"__"<<id_<<"__f"<<std::endl;
        }
    private:
        std::string name_;
        int id_;
};

class Directory : public Component{
    public:
        Directory(const char * name, int id){
            name_ = name;
            id_ = id;
        }
        virtual void Add(Component * component){
            items_.push_back(component);
        }
        virtual void DisplayInfo(){
            std::cout<<name_<<"__"<<id_<<"__d"<<std::endl;
            std::vector<Component *>::iterator com_iter;
            for (com_iter = items_.begin(); com_iter != items_.end(); com_iter++){
                std::cout<<"\t";
                (dynamic_cast<Component *>(*com_iter))->DisplayInfo();
            }
        }
    private:
        std::vector<Component * > items_;
        std::string name_;
        int id_;
};

#endif  //__TEST_COMPOSITE_H_

/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */
/**
 * @file test_composit.cpp
 * @author itege
 * @date 2014/04/02 10:33:30
 * @brief 
 *  
 **/

#include "test_composite.h"

int main(){
    File f1("file1", 101);

    Directory d1("dir1", 2001);
    d1.Add(&f1);

    File f2("file2", 201);
    Directory d2("dir2", 3001);
    d2.Add(&d1);
    d2.Add(&f2);
    
    std::cout<<"d2 info:"<<std::endl;
    d2.DisplayInfo();
    
    std::cout<<"d1 info:"<<std::endl;
    d1.DisplayInfo();

}   

输出

d2 info:
dir2__3001__d
        dir1__2001__d
        file1__101__f
        file2__201__f
d1 info:
dir1__2001__d
        file1__101__f

有个问题一直没高明白,望高人指点:

就是打印d2的时候,希望是其下面的子目录d1打印过程中也有缩进。

但是明显的d1下的f1打印的时候没有打印缩进。按理调用的应该是d1的DisplayInfo函数。

而d1打印时,其子节点应该是要先打印缩进之后才会打印的。一直没高明白。

后面有空再学习一下。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值