前进中的蜗牛

番茄大叔

水滴穿石,非一日之功;没有量变,何来质变。

合成模式(Composite)

模式定义

合成(Composite)模式:将对象组合成树形结构以表示“部分-整体”的层次结构。Composite使得用户对单个对象和组合对象的使用具有一致性。

UML类图

  • 抽象构件(component): 为参加组合的对象定义出公共的接口及其默认的行为,用来管理所有的子对象。负责对整体操作的方法有:Operation() Add(Component) Remove(Component) GetChild(int)
  • 树枝构件(Composite): 抽象构建子类,并包含抽象构建类型的集合(存放下级对象)。参加组合的有下级子对象的对象,除拥有Operation()外,还包括整体操作方法:Add(Component) Remove(Component) GetChild(int)
  • 树叶构件(Left): 抽象构建子类,没有下级子对象的对象,拥有Operation()即可

代码结构

	public static class CompositeApp
	{
		public static void Run()
		{
			Composite root = new Composite("root");
			root.Add(new Leaf("Leaf A"));
			root.Add(new Leaf("Leaf B"));

			Composite comp = new Composite("Composite X");
			comp.Add(new Leaf("Leaf XA"));
			comp.Add(new Leaf("Leaf XB"));

			root.Add(comp);
			root.Add(new Leaf("Leaf C"));

			root.Display(1);
			Console.ReadKey();
		}
	}

	abstract class Component
	{
		protected string name;

		public Component(string name)
		{
			this.name = name;
		}

		public abstract void Add(Component c);
		public abstract void Remove(Component c);
		public abstract void Display(int depth);
	}

	class Composite : Component
	{
		private List<Component> _children = new List<Component>();

		public Composite(string name) : base(name)
		{
		}

		public override void Add(Component c)
		{
			_children.Add(c);
		}

		public override void Display(int depth)
		{
			Console.WriteLine(new string('-', depth) + name);

			foreach (Component component in _children)
			{
				component.Display(depth + 2);
			}
		}

		public override void Remove(Component c)
		{
			_children.Remove(c);
		}
	}

	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);
		}
	}

情景案例

这里以画一副画为例,一幅画有好多元素组成,每种元素都有展示方法Display(int indent); 。但有的是独立的元素(树叶节点),有的是组合元素(树枝节点)。
其实Asp.Net WebForm 中的Control就是组合机构,有个控件可以包含其它控件

public static class MainApp
	{
		public static void Run()
		{
			CompositeElement root = new CompositeElement("Picture");
			root.Add(new PrimitiveElement("Red Line"));
			root.Add(new PrimitiveElement("Blue Circle"));
			root.Add(new PrimitiveElement("Green Box"));

			CompositeElement comp = new CompositeElement("Two Circles");
			comp.Add(new PrimitiveElement("Black Circle"));
			comp.Add(new PrimitiveElement("White Circle"));
			root.Add(comp);

			PrimitiveElement pe = new PrimitiveElement("Yellow Line");
			root.Add(pe);
			root.Remove(pe);

			root.Display(1);
			Console.ReadKey();
		}
	}

	/// <summary>
	/// 画元素
	/// </summary>
	abstract class DrawingElement
	{
		protected string _name;
		public DrawingElement(string name)
		{
			this._name = name;
		}

		public abstract void Add(DrawingElement d);
		public abstract void Remove(DrawingElement d);
		public abstract void Display(int indent);
	}

	/// <summary>
	/// 单独元素
	/// </summary>
	class PrimitiveElement : DrawingElement
	{
		public PrimitiveElement(string name): base(name)
		{
		}

		public override void Add(DrawingElement c)
		{
			Console.WriteLine("Cannot add to a PrimitiveElement");
		}

		public override void Remove(DrawingElement c)
		{
			Console.WriteLine( "Cannot remove from a PrimitiveElement");
		}

		public override void Display(int indent)
		{
			Console.WriteLine(new String('-', indent) + " " + _name);
		}
	}

	/// <summary>
	/// 组合元素
	/// </summary>
	class CompositeElement : DrawingElement
	{
		private List<DrawingElement> elements = new List<DrawingElement>();

		public CompositeElement(string name) : base(name)
		{
		}

		public override void Add(DrawingElement d)
		{
			elements.Add(d);
		}

		public override void Remove(DrawingElement d)
		{
			elements.Remove(d);
		}

		public override void Display(int indent)
		{
			Console.WriteLine(new String('-', indent) + "+ " + _name);

			foreach (DrawingElement d in elements)
			{
				d.Display(indent + 2);
			}
		}
	}
posted @ 2018-02-01 19:45  LoveTomato  阅读(228)  评论(0编辑  收藏  举报