09_组合模式
组合模式是一种结构型设计模式,它允许我们将对象组合成树状结构,以表示“整体-部分”的层次结构。组合模式使得客户端可以统一地处理单个对象和组合对象,无需区分它们的差异。
组合模式有三个主要角色:
-
组件(Component):定义了组合中的对象的公共接口,可以是抽象类或接口,并提供了一些默认的实现。
-
叶子节点(Leaf):表示组合中的叶子节点对象,它没有子节点。
-
容器节点(Composite):表示组合中的容器节点对象,它可以包含其他子节点。
组合模式的工作原理如下:
-
所有的组件都实现了统一的组件接口。
-
叶子节点实现了组件接口,并定义了叶子节点特有的行为。
-
容器节点实现了组件接口,并维护了一个子节点的列表。容器节点可以添加、删除和遍历子节点。
-
客户端通过调用组件接口的方法,可以统一地处理单个对象和组合对象。
组合模式的优点包括:
-
可以统一地对单个对象和组合对象进行操作,简化了客户端的代码。
-
可以以相同的方式处理组合对象和单个对象,提高了代码的可维护性和扩展性。
-
可以通过组合对象的嵌套来构建复杂的层次结构。
组合模式适用于以下场景:
-
当需要表示对象的层次结构,并希望以统一的方式处理单个对象和组合对象时,可以使用组合模式。
-
当希望客户端能够忽略组合对象与单个对象之间的差异,统一地操作它们时,可以使用组合模式。
总结而言,组合模式通过将对象组合成树状结构,使得客户端可以统一地处理单个对象和组合对象。它提供了一种处理对象层次结构的方式,简化了客户端的代码,并提高了代码的可维护性和扩展性。
Component
/// <summary> /// 抽象组件,统一接口 /// </summary> public abstract class Component { public string _name; public Component(string name) { _name = name; } /// <summary> /// 添加 /// </summary> /// <param name="component"></param> public abstract void Add(Component component); /// <summary> /// 删除 /// </summary> /// <param name="component"></param> public abstract void Remove(Component component); /// <summary> /// 展示 /// </summary> /// <param name="depth"></param> public abstract void Display(int depth); }
Composite
/// <summary> /// 枝节点 /// </summary> public class Composite : Component { private List<Component> children = new List<Component>(); public Composite(string name) : base(name) { } public override void Add(Component component) { children.Add(component); } public override void Display(int depth) { Console.WriteLine(new String('-', depth) + _name); foreach (Component component in children) { component.Display(depth+1); } } public override void Remove(Component component) { children.Remove(component); } }
Leaf
public class Leaf : Component { public Leaf(string name) : base(name) { } public override void Add(Component component) { throw new Exception("叶节点不能添加子项"); } public override void Display(int depth) { Console.WriteLine(new String('-', depth) + _name); } public override void Remove(Component component) { throw new Exception("叶节点不能删除子项"); } }
调用
public class Client { public void Start() { Component movie1 = new Leaf("电影01");//叶节点 Component movie2 = new Leaf("电影02"); Component movie3 = new Leaf("电影03"); Component node1 = new Composite("喜剧片");//枝节点 node1.Add(movie1); node1.Add(movie2); node1.Add(movie3); Component movie4 = new Leaf("电影04");//叶节点 Component movie5 = new Leaf("电影05"); Component movie6= new Leaf("电影06"); Component node2 = new Composite("科幻片");//枝节点 node2.Add(movie4); node2.Add(movie5); node2.Add(movie6); Component root = new Composite("电影"); root.Add(node1); root.Add(node2); root.Display(1); } }
static void Main(string[] args) { new Client().Start(); Console.ReadKey(); Console.WriteLine("Hello, World!"); }