与我们上图中文件系统图例对应
不管是菜单还是菜单项,都应该继承自统一的接口,这里我们创建一个抽象组件,定义一些通用的方法,如添加,删除,打印。
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
下,从而构建了一个树形结构。
在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。
组合模式正是应树形结构而生,所以组合模式的使用场景就是出现树形结构的地方。比如:文件目录显示,多级目录呈现等树形结构数据的操作。