组合模式:将对象组合成树形结构以表示“整体-部分”的关系
比较形象的比喻,俄罗斯套娃
例子,比如一个文件下有ppt,word,子文件夹,子文件下又可以装东西
一个公司下可以有很多部门,部门下有员工
如果当前节点为word就不能创建文件夹了,只能编辑,所以组合模式分为透明式和安全式
透明式:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 透明式组合模式
{
public abstract class Folder
{
public abstract void Add(Folder folder);
public abstract void Remove(Folder folder);
public abstract void Open();
}
public sealed class Word : Folder
{
//因为word下无法创建文件,所以抛出异常
public override void Add(Folder folder)
{
throw new NotImplementedException();
}
public override void Open()
{
Console.WriteLine("打开word开始编辑");
}
public override void Remove(Folder folder)
{
throw new NotImplementedException();
}
}
public class SonFolder : Folder
{
public override void Add(Folder folder)
{
Console.WriteLine("在当前目录下添加文件");
}
public override void Open()
{
Console.WriteLine("打开文件");
}
public override void Remove(Folder folder)
{
Console.WriteLine("在当前目录下删除文件");
}
}
class Program
{
static void Main(string[] args)
{
Folder myword = new Word();
myword.Open();
//word下不可创建文件会抛出异常,所以这是透明式的短板
//myword.Add(new SonFolder());
//myword.Remove(new SonFolder());
Folder myfolder = new SonFolder();
myfolder.Open();
myfolder.Add(new SonFolder());
myfolder.Remove(new SonFolder());
}
}
}
透明式把抽象构件父类的抽象方法都申明出来,导致子类没有该功能也要重写,显得不安全
而安全式,抽象构件父类只写了子类共有的方法,比如open方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 安全式组合模式
{
public abstract class Folder
{
public abstract void Open();
}
public sealed class Word : Folder
{
public override void Open()
{
Console.WriteLine("打开word开始编辑");
}
}
public abstract class SonFolder : Folder
{
public abstract void Add(Folder folder);
public abstract void Remove(Folder folder);
public override void Open()
{
Console.WriteLine("打开当前文件");
}
}
public class NextFolder : SonFolder
{
public override void Add(Folder folder)
{
Console.WriteLine("添加文件");
}
public override void Remove(Folder folder)
{
Console.WriteLine("删除文件");
}
public override void Open()
{
Console.WriteLine("打开当前文件");
}
}
class Program
{
static void Main(string[] args)
{
Folder myword = new Word();
myword.Open();
Folder nextfolder = new NextFolder();
nextfolder.Open();
(nextfolder as SonFolder).Add(new NextFolder());
(nextfolder as SonFolder).Remove(new NextFolder());
}
}
}