欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

设计模式—组合模式

程序员文章站 2022-06-03 08:33:51
...

引用:https://www.cnblogs.com/guyun/p/6183647.html

定义:组合模式主要用来处理一类具有“容器特征”的对象——即它们在充当对象的同时,又可以作为容器包含其他多个对象。

要了解组合模式,首先要理解递归,什么是递归简单的来说就是能自己调用自己。常用的使用场景有,在个文件夹下,读取所有的文件。

using System;
using System.Collections.Generic;
using System.IO;

namespace prototypeModel
{
    //递归
    //
    class Program
    {
       static List<FileInfo> lstFile = new List<FileInfo>();
        static void Main(string[] args)
        {
            DirectoryInfo dirinfo = new DirectoryInfo(@"G:\KuGou");//选择一个路径
            FileInfo[] files = dirinfo.GetFiles();//获取根目录
            AddLst(files);//添加到容器中
            CountFileNumber(dirinfo);
        }
         //如果我们不使用递归,则需要一层一层往下遍历,这是很头疼的,而且你不知道里面到底有几层
        static void CountFileNumber(DirectoryInfo dirinfo)
        {
            DirectoryInfo[] directoryInfos= dirinfo.GetDirectories();
            foreach (DirectoryInfo item in directoryInfos)
            {
                FileInfo[] files1 = item.GetFiles();
                AddLst(files1);
                CountFileNumber(item);
            }  
        }
        static void AddLst(FileInfo[] files)
        {
            foreach (FileInfo fileInfo in files)
            {
                lstFile.Add(fileInfo);
            }
        }
    }
}

递归的特点:1.有出口(不满足相应条件则退出)

                    2.有传参(有参数自己调用自己)

                     3.消耗资源

下面是组合模式类图

设计模式—组合模式

组合模式中涉及到三个角色:

  • 抽象构件(Component)角色:这是一个抽象角色,上面实现中Graphics充当这个角色,它给参加组合的对象定义出了公共的接口及默认行为,可以用来管理所有的子对象(在透明式的组合模式是这样的)。在安全式的组合模式里,构件角色并不定义出管理子对象的方法,这一定义由树枝结构对象给出。
  • 树叶构件(Leaf)角色:树叶对象时没有下级子对象的对象,上面实现中Line和Circle充当这个角色,定义出参加组合的原始对象的行为
  • 树枝构件(Composite)角色:代表参加组合的有下级子对象的对象,上面实现中ComplexGraphics充当这个角色,树枝对象给出所有管理子对象的方法实现,如Add、Remove等。
  • 举个例子:(获取C盘下面所有的文件,文件(leaf角色),文件夹(树枝结构)
        //抽象构件,它是叶子和容器共同的父类,并且声明了叶子和容器的所有方法
        abstract class AbstractFile
        {
            public abstract void Add(AbstractFile file);//新增文件
            public abstract void Delete(AbstractFile file);//删除文件
            public abstract AbstractFile GetChildFile(int i);//获取子构件(可以使文件,也可以是文件夹)
            public abstract void KillVirue();//对文件进行杀毒
        }
    
        class Folder:AbstractFile//文件夹(容器)
        {
            private List<AbstractFile> fileList = new List<AbstractFile>();
            private string name;
            public Folder(string name)
            {
                this.name = name;
            }
            public string Name
            {
                get { return name; }
                set { name = value; }
            }
            public override void Add(AbstractFile file)
            {
                fileList.Add(file);
            }
     
            public override void Delete(AbstractFile file)
            {
                fileList.Remove(file);
            }
     
            public override AbstractFile GetChildFile(int i)
            {
                return fileList[i] as AbstractFile;
            }
     
            public override void KillVirue()
            {
                Console.WriteLine("对文件夹{0}进行杀毒",name);
                foreach (AbstractFile obj in fileList)
                {
                    obj.KillVirue();
                }
            }
        }
    class ImageFile:AbstractFile//图片文件(leaf)
        {
            private string name;
     
            public string Name
            {
                get { return name; }
                set { name = value; }
            }
            public ImageFile(string name)
            {
                this.name = name;
            }
            public override void Add(AbstractFile file)
            {
                Console.WriteLine("对不起,不支持该方法");
            }
            public override void Delete(AbstractFile file)
            {
                Console.WriteLine("对不起,不支持该方法");
            }
            public override AbstractFile GetChildFile(int i)
            {
                Console.WriteLine("对不起,不支持该方法");
                return null;
            }
            public override void KillVirue()
            {
                //模拟杀毒
                Console.WriteLine("已经对{0}进行了杀毒", name);
            }
        }
        class Program(客户端调用)
        {
            static void Main(string[] args)
            {
                AbstractFile file1, file2, folder1,file3, folder2, folder3;
                folder1 = new Folder("我的视频");
                folder2 = new Folder("我的图片");
                folder3 = new Folder("我的资料");
     
                file1 = new TextFile("文本1");
     
                file2 = new ImageFile("图像2");
                file3 = new TextFile("文本2");
                folder1.Add(file1);
                folder2.Add(file2);
                folder2.Add(file3);
                folder2.KillVirue();
                Console.ReadLine();
            }
        }
    
    

组合模式分安全式的组合模式和透明式组合模式:看抽象类有没有增删改查的抽象方法,有的话则为透明式组合模式,否则为安全式组合模式。

      在以下情况下应该考虑使用组合模式:

  1. 需要表示一个对象整体或部分的层次结构。
  2. 希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

 

相关标签: 组合模式