Composite 组合模式 部分-整体 树 递归

本文介绍了组合模式的基本概念,展示了如何通过组合模式将对象组织成树形结构以表示部分-整体的关系,使得用户能一致地处理单个对象和组合对象。文章通过具体示例详细解释了组合模式的实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介 

《大话设计模式》一书中对组合模式的定义为: 将对象组合成【树】形结构以表示【部分-整体】的层次结构,组合模式使得用户对【单个对象】和对【组合对象】的使用具有一致性

组合模式有时候又叫做部分-整体模式,它使我们在树型结构的问题中, 模糊了简单元素和复杂元素的概念
当发现需求中是体现 部分与整体层次结构,并且你希望用户可以 忽略组合对象与单个对象的不同,以统一的方式使用组合结构中的所有对象时,就应该考虑组合模式了。
组合模式解耦了客户程序与复杂元素内部结构,从而使客户程序可以像处理简单元素一样来处理复杂元素。

组合模式让你可以优化处理 【递归】或【分级】数据结构。
关于分级数据结构的一个普遍性的例子是你每次使用电脑时所遇到的 文件系统。文件系统由 目录和文件组成,每个目录都可以装内容,目录的内容可以是文件,也可以是目录。按照这种方式,计算机的文件系统就是以 递归结构来组织的。如果你想要描述这样的数据结构,那么你可以使用组合模式。

涉及角色:
  • Component:为参加组合的对象声明一个公共接口,不管是组合还是叶结点
  • Leaf:在组合中表示叶子结点对象,叶子结点没有子结点
  • Composite:表示参加组合的子结点的对象

特点:使得客户端看来单个对象和对象的组合是同等的。换句话说,某个类型的方法同时也接受自身类型作为参数。
例如:java.util.List#addAll(Collection)

组合模式

Component:为参加组合的对象声明一个公共接口,不管是组合还是叶结点。
public abstract class Component {
    /**表示直接叶子节点(直接下属团队成员)的集合 */
    protected List<Component> employList;
    public String name;
    
    public final void display() {
        System.out.println(name);//打印自己
        display(employList);//打印子节点
    }
    
    private final void display(List<Component> list) {
        if (list != null) {
            for (int i = 0; i < list.size(); i++) {
                Component sonComponent = list.get(i);//子节点
                System.out.println(sonComponent.name);//打印子节点
                List<Component> sonList = sonComponent.employList;//子节点的节点集合 
                if (sonList != null) {//不为空说明是非叶子节点
                    display(sonList);
                }
            }
        }
    }
    
    public abstract boolean add(Component employer);
    public abstract boolean delete(Component employer);
}
 
1
public abstract class Component {
2
    /**表示直接叶子节点(直接下属团队成员)的集合 */
3
    protected List<Component> employList;
4
    public String name;
5
    
6
    public final void display() {
7
        System.out.println(name);//打印自己
8
        display(employList);//打印子节点
9
    }
10
    
11
    private final void display(List<Component> list) {
12
        if (list != null) {
13
            for (int i = 0; i < list.size(); i++) {
14
                Component sonComponent = list.get(i);//子节点
15
                System.out.println(sonComponent.name);//打印子节点
16
                List<Component> sonList = sonComponent.employList;//子节点的节点集合 
17
                if (sonList != null) {//不为空说明是非叶子节点
18
                    display(sonList);
19
                }
20
            }
21
        }
22
    }
23
    
24
    public abstract boolean add(Component employer);
25
    public abstract boolean delete(Component employer);
26
}

Leaf:组合中的叶子结点对象,叶子结点没有子结点
public class Leaf extends Component {
    public Leaf(String name) {
        this.name = name;
        this.employList = null;//没有叶子节点
    }
    
    @Override
    public boolean add(Component employer) {
        throw new RuntimeException("叶子结点没有子结点"); 
    }
    @Override
    public boolean delete(Component employer) {
        throw new RuntimeException("叶子结点没有子结点"); 
    }
}
x
 
1
public class Leaf extends Component {
2
    public Leaf(String name) {
3
        this.name = name;
4
        this.employList = null;//没有叶子节点
5
    }
6
    
7
    @Override
8
    public boolean add(Component employer) {
9
        throw new RuntimeException("叶子结点没有子结点"); 
10
    }
11
    @Override
12
    public boolean delete(Component employer) {
13
        throw new RuntimeException("叶子结点没有子结点"); 
14
    }
15
}

Composite:组合中有子结点对象
public class Composite extends Component {
    public Composite(String name) {
        this.name = name;
        this.employList = new ArrayList<Component>(); 
    }
    
    @Override
    public boolean add(Component employer) {
        return this.employList.add(employer);
    }
    @Override
    public boolean delete(Component employer) {
        return this.employList.remove(employer);
    }
}
 
1
public class Composite extends Component {
2
    public Composite(String name) {
3
        this.name = name;
4
        this.employList = new ArrayList<Component>(); 
5
    }
6
    
7
    @Override
8
    public boolean add(Component employer) {
9
        return this.employList.add(employer);
10
    }
11
    @Override
12
    public boolean delete(Component employer) {
13
        return this.employList.remove(employer);
14
    }
15
}

演示

public class Test {
    public static void main(String[] args) {
        Component employer1 = new Composite("【项目经理一】"); 
        Component employer11 = new Leaf("包青天");
        Component employer12 = new Leaf("白乾涛");
        Component employer13 = new Leaf("baiqiantao");
        
        Component employer2 = new Composite("【项目经理二】"); 
        Component employer21 = new Leaf("bqt");
        
        Component employer3 = new Composite("boss");
        employer3.add(employer1);// 为boss添加一个非叶子节点
        employer3.add(employer2);
        
        employer1.add(employer11);// 为项目经理添加一个叶子节点 
        employer1.add(employer12);
        employer1.add(employer13);
        
        employer2.add(employer21);
        
        employer11.display();
        System.out.println("----------------------------------");
        employer1.display();
        System.out.println("----------------------------------");
        employer2.display();
        System.out.println("----------------------------------");
        employer3.display();
        System.out.println("----------------------------------");
        
        System.out.println(employer2.add(employer21));//true
        System.out.println(employer2.delete(employer11));//false
        employer2.display();
    }
}
x
 
1
public class Test {
2
    public static void main(String[] args) {
3
        Component employer1 = new Composite("【项目经理一】"); 
4
        Component employer11 = new Leaf("包青天");
5
        Component employer12 = new Leaf("白乾涛");
6
        Component employer13 = new Leaf("baiqiantao");
7
        
8
        Component employer2 = new Composite("【项目经理二】"); 
9
        Component employer21 = new Leaf("bqt");
10
        
11
        Component employer3 = new Composite("boss");
12
        employer3.add(employer1);// 为boss添加一个非叶子节点
13
        employer3.add(employer2);
14
        
15
        employer1.add(employer11);// 为项目经理添加一个叶子节点 
16
        employer1.add(employer12);
17
        employer1.add(employer13);
18
        
19
        employer2.add(employer21);
20
        
21
        employer11.display();
22
        System.out.println("----------------------------------");
23
        employer1.display();
24
        System.out.println("----------------------------------");
25
        employer2.display();
26
        System.out.println("----------------------------------");
27
        employer3.display();
28
        System.out.println("----------------------------------");
29
        
30
        System.out.println(employer2.add(employer21));//true
31
        System.out.println(employer2.delete(employer11));//false
32
        employer2.display();
33
    }
34
}
2018-2-22




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值