我是靠谱客的博主 清秀蛋挞,最近开发中收集的这篇文章主要介绍“部分-整体“——组合模式,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一、组合模式概述

1.定义:
组合模式(Composite),将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

2.例子:
在这里插入图片描述
3.分析:
在树形目录结构中,包含文件和文件夹两类不同的元素。
在文件夹中可以包含文件,还可以继续包含子文件夹,在文件中不能再包含子文件或者子文件夹。
文件夹 —>容器(Container)
文件 —>叶子(Leaf)

4.理解:
一致地对待容器对象和叶子对象。
当容器对象的某一个方法被调用时,将遍历整个树形结构,寻找也包含这个方法的成员对象并调用执行,牵一而动百,其中使用了递归调用的机制来对整个结构进行处理
由于容器对象和叶子对象在功能上的区别,在使用这些对象的代码中必须有区别地对待容器对象和叶子对象,而实际上大多数情况下客户端希望一致地处理它们,因为对于这些对象的区别对待将会使程序非常复杂
在这里插入图片描述
5.结构:
组合模式包含以下3个角色:Component(抽象构件)、Leaf(叶子构件)、Composite(容器构件)

二、组合模式适用环境

1.在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,客户端可以一致地对待它们
2.在一个使用面向对象语言开发的系统中需要处理一个树形结构
3.在一个系统中能够分离出叶子对象和容器对象,而且它们的类型不固定,需要增加一些新的类型

三、组合模式案例

1.案例:
软件公司欲开发一个杀毒软件,该软件既可以对某个文件夹(Folder)杀毒,也可以对某个指定的文件(File)进行杀毒。该杀毒软件还可以根据各类文件的特点,为不同类型的文件提供不同的杀毒方式,例如图像文件(ImageFile)和文本文件(TextFile)的杀毒方式就有所差异。现使用组合模式来设计该杀毒软件的整体框架。
2.类图:
在这里插入图片描述
(1) AbstractFile:抽象文件类,充当抽象构件类
(2) ImageFile:图像文件类,充当叶子构件类
(3) TextFile:文本文件类,充当叶子构件类
(4) Folder:文件夹类,充当容器构件类
(5) Client:客户端测试类
3.代码:

package composite;

/**
 * 抽象文件类,充当抽象构件类
 */
public abstract class AbstractFile {

    public abstract void add(AbstractFile file); //添加元素
    public abstract void remove(AbstractFile file); //删除元素
    public abstract void killVirus(); //模拟杀毒
}

package composite;

import java.util.ArrayList;

/**
 * 文件夹类,充当容器构件类
 */
public class Folder extends AbstractFile {

    //定义一个fileList的集合,用来存储AbstractFile类型的成员
    private ArrayList<AbstractFile> fileList = new ArrayList<>();
    private String name; //定义文件夹名

    //无参构造
    public Folder() {
    }

    //有参构造
    public Folder(String name) {
        this.name = name;
    }

    @Override
    public void add(AbstractFile file) {
        fileList.add(file);
    }

    @Override
    public void remove(AbstractFile file) {
        fileList.remove(file);
    }

    @Override
    public void killVirus() {
        System.out.println("系统正在对‘" + name + "’进行杀毒");

        //利用foreach循环对fileList集合里的所有元素进行杀毒
        for (AbstractFile abstractFile : fileList) {
            abstractFile.killVirus();
        }
    }
}

package composite;

/**
 * 图像文件类,充当叶子构件类
 */
public class ImageFile extends AbstractFile {

    private String name; //定义文件名

    //无参构造
    public ImageFile() {
    }

    //有参构造
    public ImageFile(String name) {
        this.name = name;
    }

    @Override
    public void add(AbstractFile file) {
        System.out.println("对不起,不支持该方法!");
    }

    @Override
    public void remove(AbstractFile file) {
        System.out.println("对不起,不支持该方法!");
    }

    @Override
    public void killVirus() {
        System.out.println("系统正在对‘" + name + "’进行图像杀毒");
    }
}

package composite;

/**
 * 文本文件类,充当叶子构件类
 */
public class TextFile extends AbstractFile {

    private String name; //定义文件名

    //无参构造
    public TextFile() {
    }

    //有参构造
    public TextFile(String name) {
        this.name = name;
    }

    @Override
    public void add(AbstractFile file) {
        System.out.println("对不起,不支持该方法!");
    }

    @Override
    public void remove(AbstractFile file) {
        System.out.println("对不起,不支持该方法!");
    }

    @Override
    public void killVirus() {
        System.out.println("系统正在对‘" + name + "’进行文本杀毒");
    }
}

package composite;

/**
 * 客服端测试类
 */
public class Client {

    public static void main(String[] args) {

        /*
        1.创建对象
         */
        //创建文件夹对象
        AbstractFile folder = new Folder("Bei-Zhen的资料");
        //创建子文件夹对象
        AbstractFile subfolder1 = new Folder("图像文件夹");
        AbstractFile subfolder2 = new Folder("文本文件夹");
        //创建文件对象(图像文件或文本文件)
        AbstractFile file1 = new ImageFile("百度登录流程图.jpg");
        AbstractFile file2 = new ImageFile("猜拳流程图.png");
        AbstractFile file3 = new TextFile("设计模式.txt");
        AbstractFile file4 = new TextFile("面向对象基础.doc");

        /*
        2.向集合中添加元素
         */
        //把文件添加到相对应的子文件夹中
        subfolder1.add(file1);
        subfolder1.add(file2);
        subfolder2.add(file3);
        subfolder2.add(file4);
        //把子文件夹添加到文件夹中
        folder.add(subfolder1);
        folder.add(subfolder2);

        /*
        3.对文件夹杀毒
         */
        System.out.println("---------------杀毒软件--------------------");
        System.out.println("------文件夹杀毒开始,正在闪电杀毒-----------");
        folder.killVirus();
        System.out.println("------文件夹杀毒完成,感谢你的使用-----------");
        System.out.println();

        /*
        4.对指定文件杀毒
         */
        System.out.println("------指定文件杀毒开始,正在闪电杀毒---------");
        file1.killVirus();
        System.out.println("------指定文件杀毒完成,感谢你的使用---------");

    }
}

4.代码运行截图:
在这里插入图片描述

四、组合模式优缺点

1.优点:
(1)可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,让客户端忽略了层次的差异,方便对整个层次结构进行控制
(2)客户端可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了客户端代码
(3)增加新的容器构件和叶子构件都很方便,符合开闭原则
(4)为树形结构的面向对象实现提供了一种灵活的解决方案
2.缺点:
在增加新构件时很难对容器中的构件类型进行限制

最后

以上就是清秀蛋挞为你收集整理的“部分-整体“——组合模式的全部内容,希望文章能够帮你解决“部分-整体“——组合模式所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部