组合模式(Composite)


    组合模式将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。


组合模式结构




    组合模式非常好的解决了一个整体与部分可以被一致对待的问题。那么,什么叫“整体与部分可以一致对待”呢?


    例如:对于一个公司的组织结构的处理:在总公司中包含人力资源部,财务部,分公司。其中人力资源部和财务部是不可再分的,但是分公司下面可以像总公司那样,有自己的人力资源部,财务部,子公司。这是,对于整体的处理和对于部分的处理,是一样 的,既然有重复,那么就可以用相同的方式处理它们。


   


   组合模式这样就定义了包含人力资源部和财务部这些基本对象和分公司,办事处等组合对象的类层次结构。基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断地递归下去,客户代码中,任何用到基类对象的地方都可以使用组合对象了。


   还有就是用户不用关心到底是处理一个叶节点还是处理一个组合组件,也就用不着为定义组合而写一些选择判断语句了。


 示例

      在学习数据库的时候,里面数据模型叫做层次模型。层次结构中,典型的代表就是文件目录的组织结构。文件夹中包含文件和文件夹,然后文件夹里面又包含文件和文件夹,然后文件夹里面又包含文件和文件夹。。。。。。


    如果我们自己写一个文件管理系统的话,就可以用这种结构来模拟文件系统啦~  for example:

 

namespace 组合模式示例
{
    //定义抽象的component
    abstract class ComponentFile
    {
        protected string name;  //文件夹名称
        public ComponentFile(string name) //构造时顺便起个名字
        {
            this.name = name;
        }

        public abstract void New(ComponentFile c);  //新建
        public abstract void Delete(ComponentFile c);   //删除
        public abstract void ShowFile(int depth);   //显示文件结构
    }

    //定义Leaf:文件夹中的文件

    class FileInFolder:ComponentFile 
    {
        public FileInFolder(string name)  //调用父类构造方法
            : base(name)
        { }

        public override void New(ComponentFile c)
        {
            Console.WriteLine("非法操作:不能再一个文件里面建立文件夹!");

        }

        public override void Delete(ComponentFile c)
        {
            Console.WriteLine("非法操作:此文件里面不包含任何文件夹。");
        }

        public override void ShowFile(int depth)
        {
            Console.WriteLine(new string('-', depth) + name);
        }

    }

    //定义Composite:文件夹
    class Folder:ComponentFile 
    {
        //定义一个集合,用来存放此文件夹下的文件夹和文件
        private List<ComponentFile> children = new List<ComponentFile>();

        public Folder(string name)  //调用父类构造方法
            : base(name)
        { }

        public override void New(ComponentFile c)
        {
            children.Add(c);
        }

        public override void Delete(ComponentFile c)
        {
            children.Remove(c);
        }

        public override void ShowFile(int depth)
        {
            //首先显示此文件夹名
            Console.WriteLine(new string('-', depth) + name);

            //然后显示此文件夹下的文件夹和文件
            foreach (ComponentFile File in children)
            {
                
                File.ShowFile(depth + 10);
                
            }
 

        }

    }



    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("以下是模仿C盘下部分目录结构:");
            Console.WriteLine("");

            Folder c=new Folder (@"C:\");
            c.New(new FileInFolder (@"temp.txt\"));
            c.New(new FileInFolder(@"7z.exe"));

            Folder windows = new Folder(@"windows\");
            windows.New(new FileInFolder(@"config.ini\"));
            windows.New(new FileInFolder(@"explore.exe"));

            c.New(windows);   //c盘下的windows

            Folder temp = new Folder(@"temp\");
            temp.New(new FileInFolder(@"iNodeSetup0\"));

            c.New(temp);  //c盘下的temp


            c.ShowFile(2);


        }
    }
}


运行下:




   

何时使用组合模式?

       当发现需求中是体现部分与整体层次的结构时,以及希望用户可以忽略组合对象与单个对象的不同,统一的使用组合结构中的所有对象时,就应该考虑用组合模式了。




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水田如雅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值