引用:c#设计模式-组合模式 - Napoléon - 博客园
定义:组合模式主要用来处理一类具有“容器特征”的对象——即它们在充当对象的同时,又可以作为容器包含其他多个对象。
要了解组合模式,首先要理解递归,什么是递归简单的来说就是能自己调用自己。常用的使用场景有,在个文件夹下,读取所有的文件。
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(); } }
组合模式分安全式的组合模式和透明式组合模式:看抽象类有没有增删改查的抽象方法,有的话则为透明式组合模式,否则为安全式组合模式。
在以下情况下应该考虑使用组合模式:
- 需要表示一个对象整体或部分的层次结构。
- 希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。