组合模式
一、组合模式简介(Brief Introduction)
组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。
二、解决的问题(What To Solve)
解决整合与部分可以被一致对待问题。
三、组合模式分析(Analysis)
1、组合模式结构

Component类:组合中的对象声明接口,在适当情况下,实现所有类共有接口的行为。声明一个接口用于访问和管理Component的子部件
Leaf类:叶节点对象,叶节点没有子节点。由于叶节点不能增加分支和树叶,所以叶节点的Add和Remove没有实际意义。
有叶节点行为,用来存储叶节点集合
Composite类:实现Componet的相关操作,比如Add和Remove操作。
children:用来存储叶节点集合
2、源代码
| 1、抽象类Component | 
| public 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 Diaplay(int depth); } | 
| 2、叶子节点Leaf 继承于Component | 
| public class Leaf:Component { 
 public Leaf(string name) :base(name) { 
 } 
 public override void Add(Component c) { Console.WriteLine("不能向叶子节点添加子节点"); } 
 public override void Remove(Component c) { Console.WriteLine("叶子节点没有子节点"); } 
 public override void Diaplay(int depth) { Console.WriteLine(new string('-',depth)+name); } } | 
| 3、组合类Composite继承于Component,拥有枝节点行为 | 
| public class Composite : Component { 
 List<Component> children; 
 public Composite(string name) :base(name) { if (children == null) { children = new List<Component>(); } } 
 public override void Add(Component c) { this.children.Add(c); } 
 public override void Remove(Component c) { this.children.Remove(c); } 
 public override void Diaplay(int depth) { Console.WriteLine(new String('-',depth)+name); foreach (Component component in children) { component.Diaplay(depth + 2); } } } 
 | 
| 4、客户端代码 | 
| static void Main(string[] args) { Composite root = new Composite("根节点root"); root.Add(new Leaf("根上生出的叶子A")); root.Add(new Leaf("根上生出的叶子B")); 
 Composite comp = new Composite("根上生出的分支CompositeX"); comp.Add(new Leaf("分支CompositeX生出的叶子LeafXA")); comp.Add(new Leaf("分支CompositeX生出的叶子LeafXB")); 
 root.Add(comp); 
 Composite comp2 = new Composite("分支CompositeX生出的分支CompositeXY"); comp2.Add(new Leaf("分支CompositeXY生出叶子LeafXYA")); comp2.Add(new Leaf("分支CompositeXY生出叶子LeafXYB")); 
 comp.Add(comp2); 
 root.Add(new Leaf("根节点生成的叶子LeafC")); Leaf leafD = new Leaf("leaf D"); root.Add(leafD); root.Remove(leafD); root.Diaplay(1); Console.Read(); } | 
3、程序运行结果

四.案例分析(Example)
1、场景
假设公司组织结构为:
--总结理
----技术部门经理
------开发人员A
------开发人员B
----销售部门经理
总经理直接领导技术部经理和销售部经理,技术部经理直接领导开发人员A和开发人员B。销售部经理暂时没有直接下属员工,随着公司规模增大,销售部门会新增销售员工。计算组织结构的总工资状况。
如下图所示
IComponent接口:此接口包括了Component和Composite的所有属性,公司每个角色都有职称Title和工资待遇Salary,Add方法把员工加入到组织团队中。
Component叶子节点:叶节点没有子节点,Add方法实现没有任何意义。
Composite组合类:此类有一个员工集合_listEmployees,Add方法向此集合中添加员工信息。
GetCost方法获得组织结构中的工资待遇总和
2、代码
| 1、接口IComponent | 
| 
 8. | 
| 2、叶节点Component | 
| 
 22. 
 | 
| 3、组合类Composite | 
| 1. public class Composite : IComponent 2. { 3. private List<IComponent> _listEmployees; 4. 5. public string Title { get; set; } 6. public decimal Salary { get; set; } 7. 8. public Composite(string Title, decimal Salary) 9. { 10. this.Title = Title; 11. this.Salary = Salary; 12. _listEmployees = new List<IComponent>(); 13. } 14. 15. public void Add(IComponent comp) 16. { 17. _listEmployees.Add(comp); 18. } 19. 20. public void GetCost(ref decimal salary) 21. { 22. salary += this.Salary; 23. 24. foreach (IComponent component in this._listEmployees) 25. { 26. component.GetCost(ref salary); 27. } 28. } 29. } | 
| 4、客户端代码 | 
| 
 33. | 
五、总结(Summary)
组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。解决整合与部分可以被一致对待问题
        
        如果你喜欢本文, 请长按二维码,关注公众号 分布式编程.
        
        作者:分布式编程
        
        出处:https://zthinker.com/
        
        本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    
 
                    
                     
                    
                 
                    
                
 
                
            
         
         
 浙公网安备 33010602011771号
浙公网安备 33010602011771号