
🐳与我们上图中文件系统图例对应
不管是菜单还是菜单项,都应该继承自统一的接口,这里我们创建一个抽象组件,定义一些通用的方法,如添加,删除,打印。
- public abstract class Component
- {
- protected string _name;
-
- public Component(string name)
- {
- _name = name;
- }
-
- public abstract void Add(Component c);
- public abstract void Remove(Component c);
- public abstract void Display(int depth);
- }
定义一个名为children的List类型的列表,用于存储Component类型的子元素,Add方法和Remove方法分别用于向children列表中添加和移除Component类型的对象。Display方法用于显示Composite对象的信息。这个方法首先打印出当前Composite对象的深度和名称,然后遍历children列表,对每个子元素调用Display方法。这样就形成了一种递归的结构,可以用来表示树形结构。
- public class Composite : Component
- {
- private List
children = new List(); -
- public Composite(string name)
- : base(name)
- {
- }
-
- public override void Add(Component component)
- {
- children.Add(component);
- }
-
- public override void Remove(Component component)
- {
- children.Remove(component);
- }
-
- public override void Display(int depth)
- {
- Console.WriteLine(new String('-', depth) + _name);
-
- foreach (Component component in children)
- {
- component.Display(depth + 2);
- }
- }
- }
因为叶子节点已经是最下级了,因此我们只需要在Display直接重写打印方法,并且不需要再进行遍历了
- public class Leaf : Component
- {
- public Leaf(string name)
- : base(name)
- {
- }
-
- public override void Add(Component c)
- {
- Console.WriteLine("Cannot add to a leaf");
- }
-
- public override void Remove(Component c)
- {
- Console.WriteLine("Cannot remove from a leaf");
- }
-
- public override void Display(int depth)
- {
- Console.WriteLine(new String('-', depth) + _name);
- }
- }
- class MyClass
- {
- public static void Main(string[] args)
- {
- // 创建一个根节点
- Component root = new Composite("root");
- // 创建两个节点
- Component node1 = new Composite("node1");
- Component node2 = new Composite("node2");
- // 创建叶子节点
- Component leaf1 = new Leaf("leaf1");
- Component leaf2 = new Leaf("leaf2");
- Component leaf3 = new Leaf("leaf3");
-
- // 构建树形结构
- root.Add(node1);
- root.Add(node2);
- node1.Add(leaf1);
- node2.Add(leaf2);
- node2.Add(leaf3);
-
- // 显示树形结构
- root.Display(1);
- }
- }
运行结果!在这个例子中,我们首先创建了一个根节点root,然后创建了两个节点node1和node2,以及三个叶子节点leaf1,leaf2和leaf3。然后我们将node1和node2添加到root下,将leaf1添加到node1下,将leaf2和leaf3添加到node2下,从而构建了一个树形结构。

在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。
组合模式正是应树形结构而生,所以组合模式的使用场景就是出现树形结构的地方。比如:文件目录显示,多级目录呈现等树形结构数据的操作。