三.结构型——组合模式

《大话设计模式第十九章》

0.《设计模式》摘录

  • 问题:
      在图形编辑器中操纵的图形对象包括:最基本的图形元素,例如直线、圆、…
     组合图形元素由基本图形元素和其它组合图形元素复合而成
      希望对组合和基本图形有一样的操控

  • 解决
     为组合对象和基本对象建立共同的超类,不必区别是组合对象还是基本对象
     组合对象内部结构形成递归的引用(或者包含)关系

  • 客户程序使用Component接口与组合对象和基本对象以相同的方式交互
    基本对象将直接做出响应
    组合对象则把收到的请求转发给内部的每个子部件

1.问题

​  公司系统是一个树状、多层的结构,总部、分公司、办事处都有相似的功能,但他们直接又是整体和部分的关系。如果将他们都有的功能进行复制有很多问题。

​  如下图,总部下面有分公司,还有小部门,小部门如同叶子,不能延展。而分公司还能延展出办事处和小部门。所以相当于总部、分公司、办事处都有管理小部门和延展出下级公司的功能,而小部门就没有这些功能。

在这里插入图片描述

​  问题的关键:想让整体和部分有一致性(相同的操作)

2.组合模式

2.1 定义

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

2.2 结构图和代码

  • 结构图

    在这里插入图片描述

Component:部件,包含叶子和composite的默认功能。声明接口用于访问和管理component子部件。

composite:相当于树枝,可以添加子部分和叶子,实现Component中抽象的方法。

leaf:树叶,不能添加和增加子部分。

  • 代码

    Component:

    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);//通常都用Add Remove方法来提供和移除树叶、树枝
    	public abstract void Display(Component c);
    }
    

    Leaf:

    class Leaf  extends Component
    {
    	public Leaf(String name)
    	{
    		this.name=name;
    	}
    	
    	public void Add(Component c)
    	{
    		System.out.println("不能添加");
    	}
    	public void Remove(Component c)
    	{
    		System.out.println("不能移除");
    	}
    	public void Display(int dept)
    	{
    		System.out.println('-'*dept+name);
    	}
    }
    

    Composite :

    class Composite  extends Component
    {
    	private List<Component>children=new List<Component>();
    	public Composite(String name)
    	{
    		this.name=name;
    	}
    	
    	public void Add(Component c)
    	{
    		children.Add(c)
    	}
    	public void Remove(Component c)
    	{
    		children.Remove(c)
    	}
    	public void Display(int dept)
    	{
    		System.out.println('-'*dept+name);
            foreach (Component component in children)
    			component.Display(depth + 1);
    	}
    }
    

    例子:

    static void Main(string args*)
    {
    	Composite root = new Composite("root");
        //生成树根root.根上长出两 叶 LeafA 和 LeafB
        root.Add(new Leaf("Leaf A"));
    	root.Add(new Leaf("Leaf B"));
        
        //根上长出分枝Composite X, 分枝上也有两叶LeafXA和 LeafXB
        Composite comp = new Composite("Composite X"); 
        comp.Add(new Leaf("Leaf XA"))
        comp.Add (new Leaf("Leaf XB"))
    	root.Add(comp);
    
        //在Composite X 上再长出分枝Composite XY,分枝上也有两叶LeafXYA和LeafXYB
        Composite comp2 = new Composite("Composite XY");
        comp2.Add(new Leaf("Leaf XYA")); 
        comp2.Add(new Leaf("Leaf XYB"));
        comp.Add(comp2);
        
        //根部又长出两叶LeafC和LeafD,可惜LeafD 没长牢,被风吹走了
    	root.Add(new Leaf("Leaf C"));			
    	Leaf leaf = new Leaf("Leaf D"); 
        root.Add(leaf);
        root.Remove(leaf);
        root.Display();
        }
    
    //结果显示
    -root
    --Leaf A
    --Leaf B
    --Composite X
    ---Leaf XA
    ---Leaf XB
    ---Composite XY 	
    ----Leaf XY
    ----Leaf XYB 
    ----Leaf C
    

3.优点

  • 什么时候使用组合模式?

    ​  当你发现需求中是体现部分与整体层次的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,从而统一地使用组合结构中的所有对象时,就应该考虑用组合模式了

  • 优点:

    • 组合模式可以定义基本对象(叶子)、组合对象(树枝和根)的类层次结构。基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断地递归下去

    • 组合模式让客户可以一致地使用组合结构和单个对象,用户是不用关心到底是处理一个叶节点还是处理一个组合组件,也就用不着为定义组合而 写一些选择判断语句了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值