设计模式--组合模式

喜夏-厌秋 提交于 2020-02-16 21:22:09

组合模式

定义:也称为 整体-部分(Part-Whole)模式,它的宗旨是通过将单个对象(叶子节点)和组合对象(树枝节点)用相同的接口进行表示,使得客户对单个对象和组合对象的

   使用具有一致性。组合模式 一般用来描述 整体 与 部分 的关系,它将对象组织到树形结构中,最顶层的节点称为根节点,根节点下面可以包含 树枝节点 和 叶子节点,

   树枝节点下面又可以包含 树枝节点 和 叶子节点。

使用场景:把部分和整体的关系用树形结构来表示,从而使客户端可以使用统一的方式处理部分对象和整体对象。

工作流程

1)         组合模式为处理树形结构提供了完美的解决方案,描述了如何将容器和叶子进行递归组合,使得用户在使用时可以一致性的对待容器和叶子。

2)         当容器对象的指定方法被调用时,将遍历整个树形结构,寻找也包含这个方法的成员,并调用执行。其中,使用了递归调用的机制对整个结构进行处理。

核心

1)         抽象构建(Component)角色:定义了叶子和容器构件的共同点

2)         叶子(leaf)构件角色:无叶子节点

3)         容器(Composite)构件角色:有容器特征,可以包含子节点

图示

 

 

 

 

package com.offcn.designpattern.compositepattern;

import java.util.ArrayList;
import java.util.List;

public class CompositepatternDemo {
    public static void main(String[] args) {
        AbstractFile a1,a2,a3,a4;
        Folder f1 = new Folder("我的收藏");
        a1 = new ImgFile("美女图片.jpg");
        a2 = new VidelFile("我的野蛮女友.avi");
        f1.add(a1);
        f1.add(a2);
        f1.killVirus();
        System.out.println("**************************");
        Folder f2 = new Folder("视频集锦");
        a3 = new VidelFile("刘老根.avi");
        a4 = new VidelFile("神雕侠侣.avi");
        f2.add(a3);
        f2.add(a4);
        f1.add(f2);
        f1.killVirus();

    }
}
//抽象构建(Component)角色
interface AbstractFile{
    void killVirus();//杀毒
}
//叶子(leaf)构件角色
class ImgFile implements AbstractFile{
    private String name;

    public ImgFile(String name) {
        this.name = name;
    }

    @Override
    public void killVirus() {
        System.out.println("---图像文件"+name+",杀毒中。。");
    }
}
//叶子(leaf)构件角色
class VidelFile implements AbstractFile{
    private String name;

    public VidelFile(String name) {
        this.name = name;
    }

    @Override
    public void killVirus() {
        System.out.println("---视频文件"+name+",杀毒中。。");
    }
}
//文件夹
class Folder implements AbstractFile{
    private String name;
    //容器(Composite)构件角色,可以存放叶子节点
    private List<AbstractFile> list = new ArrayList<AbstractFile>();

    public Folder(String name) {
        this.name = name;
    }
    public void add(AbstractFile abstractFile){
        list.add(abstractFile);
    }
    public void remove(AbstractFile abstractFile){
        list.remove(abstractFile);
    }
    public AbstractFile getChild(int index){
        return list.get(index);
    }
    @Override
    public void killVirus() {
        System.out.println("---文件夹"+name+",杀毒中。。");
        for (AbstractFile file : list) {
            file.killVirus();
        }
    }
}

输出:

应用场景

1)         操作系统的资源管理器。

2)         GUI中的容器层次图

3)         XML文件解析

4)         OA系统中,组织结构的处理

5)         Junit单元测试框架

优点

1)组合模式 屏蔽了对象系统的层次差异性(树节点和叶子节点为不同类型),将客户代码与复杂的容器对象解耦,使得客户端可以忽略层次间的差异,使用一致的行为控制

  不同层次。

2)在 组合模式 可以很方便地增加 树枝节点 和 叶子节点 对象,并对现有类库无侵入,符合 开闭原则;

缺点

1)如果类系统(树形结构)过于庞大,虽然对不同层次都提供一致性操作,但客户端仍需花费时间理清类之间的层次关系;

2)组合模式 在具体实现上违背了设计模式 接口隔离原则 或 依赖倒置原则;

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!