zoukankan      html  css  js  c++  java
  • 合成模式(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);
    			}
    		}
    	}
    
  • 相关阅读:
    nyoj_216_A problem is easy_201312051117
    nyoj_676_小明的求助_201312042142-2
    C# 堆和栈的区别?
    DataReader和DataSet区别
    SQLSERVER2008R2正确使用索引
    SQL Profiler工具简介
    (转)非常完善的Log4net详细说明
    SQL语句优化技术分析
    HashTable、HashSet和Dictionary的区别
    使用Nuget发布自己的类库包
  • 原文地址:https://www.cnblogs.com/LoveTomato/p/8400928.html
Copyright © 2011-2022 走看看