极速理解设计模式系列:5.组合模式(Composite Pattern)

简介:

四个角色:部件抽象接口角色(Component)、叶角色(Leaf)、组合类角色(Composite)、客户端角色(Client)

        部件抽象接口角色(Component):定义组合类对象的公共行为、属性和管理子部件的方法接口。

        叶角色(Leaf):实现Component的公共行为,但是无法管理子部件,为最终叶节点。

        组合类角色(Composite):实现Component的公共行为,可以管理子节点(增、删、查)。

        客户端角色(Client):通过Component控制整棵组合对象树。

         实现思路:一棵树,分为叶节点和主干节点,通过一个统一的接口可以往下添加节点和删除节点。

 类图:

        应用场景:Silverlight中一个Canvas名为Layout,需要有很多行,第一行 是一个TextBox,第二行是一个RichTextBox,第三行是RadioButton,第四行是一个复杂的组合控件名为complex其内部有 RadioButtonA、ComboBoxB、TextBoxC三个子控件。

        分析:这里实际上可以看做是一棵树型结构的容器Layout,内部有4个控件,其中3个简单控件是叶节点,最后一个复杂控件是主干,主干下面还有3个叶片节点。

        下面我们在控制台程序去演示一下如何使用Composite Pattern:

        一、部件抽象接口角色(Component)

 


 
 
  1. //部件抽象接口角色:Component 
  2. abstract class ControlComponent 
  3.     public string ControlName { get; set; } 
  4.     public double Width { get; set; } 
  5.     public double Height { get; set; } 
  6.     public int AllowInputNum { get; set; } 
  7.     abstract public void AddNode(ControlComponent con); 
  8.     abstract public void RemoveNode(ControlComponent con); 
  9.     abstract public void ShowNodeInfo(); 

        二、叶角色(Leaf)

 


 
 
  1. //叶角色:Leaf 
  2.  class ControlLeaf : ControlComponent 
  3.  { 
  4.      //叶角色没有子节点,故不能添加删除子节点 
  5.      public override void AddNode(ControlComponent con) 
  6.      { 
  7.          Console.WriteLine("叶类无法添加子节点。"); 
  8.      } 
  9.  
  10.      public override void RemoveNode(ControlComponent con) 
  11.      { 
  12.          Console.WriteLine("叶类无法移出子节点。"); 
  13.      } 
  14.  
  15.      //显示子节点信息的方法 
  16.      public override void ShowNodeInfo() 
  17.      { 
  18.          Console.WriteLine("___控件名:" + ControlName + " 控件宽度:" + Width + " 控件高度:" + Height + " 控件允许输入:" + AllowInputNum); 
  19.      } 
  20.  } 

        三、组合类角色(Composite)

 


 
 
  1. //组合类:Composite(主干类) 
  2.  class ControlComposite : ControlComponent 
  3.  { 
  4.      //子节点的容器(可以是叶节点,叶可以是下一节主干) 
  5.      private List<ControlComponent> controlList = new List<ControlComponent>(); 
  6.  
  7.      //添加和删除子节点 
  8.      public override void AddNode(ControlComponent con) 
  9.      { 
  10.          controlList.Add(con); 
  11.      } 
  12.  
  13.      public override void RemoveNode(ControlComponent con) 
  14.      { 
  15.          controlList.Remove(con); 
  16.      } 
  17.  
  18.      //显示子节点 
  19.      public override void ShowNodeInfo() 
  20.      { 
  21.          Console.WriteLine("控件名:" + ControlName + " 控件宽度:" + Width + " 控件高度:" + Height + " 控件允许输入:" + AllowInputNum); 
  22.          //递归显示其子节点树 
  23.          foreach (ControlComponent c in controlList) 
  24.          { 
  25.              c.ShowNodeInfo(); 
  26.          } 
  27.      } 
  28.  } 

        四、客户端角色(Client)

 


 
 
  1. //客户端:Client 
  2. class Program 
  3.     static void Main(string[] args) 
  4.     { 
  5.         ControlComposite controlLayout = new ControlComposite() { ControlName = "Layout", Height = 300, Width = 300 }; 
  6.         controlLayout.AddNode(new ControlLeaf() { ControlName = "___TextBox", Height = 30, Width = 180, AllowInputNum = 50 }); 
  7.         controlLayout.AddNode(new ControlLeaf() { ControlName = "___RichTextBox", Height = 35, Width = 220, AllowInputNum = 1000 }); 
  8.         controlLayout.AddNode(new ControlLeaf() { ControlName = "___RadioButton", Height = 25, Width = 300, AllowInputNum = 1 }); 
  9.  
  10.         ControlComposite complexControl = new ControlComposite() { ControlName = "complex", Height = 96, Width = 300 }; 
  11.         complexControl.AddNode(new ControlLeaf() { ControlName = "___RadioButtonA", Height = 33, Width = 180, AllowInputNum = 50 }); 
  12.         complexControl.AddNode(new ControlLeaf() { ControlName = "___ComboBoxB", Height = 33, Width = 100 }); 
  13.         complexControl.AddNode(new ControlLeaf() { ControlName = "___TextBoxC", Height = 30, Width = 100 }); 
  14.  
  15.         controlLayout.AddNode(complexControl); 
  16.         // controlLayout.RemoveNode(complexControl); 
  17.  
  18.         controlLayout.ShowNodeInfo(); 
  19.  
  20.         Console.ReadLine(); 
  21.     } 

        如需源码请点击 CompositePattern.rar 下载。



本文转自程兴亮 51CTO博客,原文链接:http://blog.51cto.com/chengxingliang/826952

相关文章
|
存储 缓存 安全
如何保证接口幂等性,幂等性到底是干什么的
本文介绍了幂等性原则及其在程序中的应用。首先定义了幂等性,即无论执行多少次,结果不变的特性,并区分了幂等与非幂等操作。接着详细探讨了实现幂等性的策略,如使用唯一标识符、幂等性标记字段、乐观锁版本控制等。最后,通过Java示例展示了如何实现无状态幂等操作,并强调了幂等性在分布式系统和高并发场景下的重要性。
922 0
|
API 索引
Elasticsearch Index Shard Allocation 索引分片分配策略
Elasticsearch Index Shard Allocation 索引分片分配策略
382 1
解决ERROR: Cannot uninstall ‘PyYAML‘. It is a distutils installed project and thus we cannot accuratel
解决ERROR: Cannot uninstall ‘PyYAML‘. It is a distutils installed project and thus we cannot accuratel
2328 0
解决ERROR: Cannot uninstall ‘PyYAML‘. It is a distutils installed project and thus we cannot accuratel
|
分布式计算 资源调度 大数据
【大数据优化】(二)MapReduce 优化方法
【大数据优化】(二)MapReduce 优化方法
570 0
【大数据优化】(二)MapReduce 优化方法
|
存储 JavaScript 对象存储
JS 进阶 (六) 浏览器事件模型DOM操作(2)
JS 事件 事件是元素(或者浏览器)天生自带的行为,只要行为处罚,就会触发相关的事件 xxx.onclick = function(){} 属于事件绑定,给这个事件行为绑定方法,行为触发的时候 事件参考文档
194 0
|
7天前
|
存储 弹性计算 人工智能
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
2025年9月24日,阿里云弹性计算团队多位产品、技术专家及服务器团队技术专家共同在【2025云栖大会】现场带来了《通用计算产品发布与行业实践》的专场论坛,本论坛聚焦弹性计算多款通用算力产品发布。同时,ECS云服务器安全能力、资源售卖模式、计算AI助手等用户体验关键环节也宣布升级,让用云更简单、更智能。海尔三翼鸟云服务负责人刘建锋先生作为特邀嘉宾,莅临现场分享了关于阿里云ECS g9i推动AIoT平台的场景落地实践。
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
|
5天前
|
云安全 人工智能 自然语言处理
阿里云x硅基流动:AI安全护栏助力构建可信模型生态
阿里云AI安全护栏:大模型的“智能过滤系统”。
|
5天前
|
人工智能 自然语言处理 自动驾驶
关于举办首届全国大学生“启真问智”人工智能模型&智能体大赛决赛的通知
关于举办首届全国大学生“启真问智”人工智能模型&智能体大赛决赛的通知
|
Linux 虚拟化 iOS开发
VMware Workstation Pro 25H2 for Windows & Linux - 领先的免费桌面虚拟化软件
VMware Workstation Pro 25H2 for Windows & Linux - 领先的免费桌面虚拟化软件
1090 4