【Java设计模式11】——组合模式

转载:http://www.cnblogs.com/chenssy/p/3299719.html

一、组合模式定义

组合模式组合多个对象形成树形结构以表示“整体-部分”的结构层次。

组合模式对单个对象(叶子对象)和组合对象(组合对象)具有一致性,它将对象组织到树结构中,可以用来描述整体与部分的关系。同时它也模糊了简单元素(叶子对象)和复杂元素(容器对象)的概念,使得客户能够像处理简单元素一样来处理复杂元素,从而使客户程序能够与复杂元素的内部结构解耦。

计算机的文件系统由文件和目录组成,目录下面也可以包含文件或者目录,计算机的文件系统是用递归结构来进行组织的,对于这样的数据结构是非常适用使用组合模式的。

在使用组合模式中需要注意一点也是组合模式最关键的地方:叶子对象和组合对象实现相同的接口。这就是组合模式能够将叶子节点和对象节点进行一致处理的原因。

二、模式结构

这里写图片描述

组合模式主要包含如下几个角色:

  1. Component :组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component子部件。

  2. Leaf:叶子对象。叶子结点没有子结点。

  3. Composite:容器对象,定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加(add)和删除(remove)等。

从模式结构中我们看出了叶子节点容器对象都实现Component接口,这也是能够将叶子对象和容器对象一致对待的关键所在。

三、模式实现

在文件系统中,可能存在很多种格式的文件,如果图片,文本文件、视频文件等等,这些不同的格式文件的浏览方式都不同,同时对文件夹的浏览就是对文件夹中文件的浏览,但是对于客户而言都是浏览文件,两者之间不存在什么差别,现在只用组合模式来模拟浏览文件。UML结构图:

这里写图片描述

File接口或抽象类:

package com.tao.pattern.composite;

/**
 * Created by michael on 17-8-7.
 */

/**
 * 文件抽象类。
 * 所有类型的文件或者文件夹都必须继承它。
 */
public abstract class File {

    protected String name;

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

    public abstract void display();

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

Folder文件夹类:

package com.tao.pattern.composite;

/**
 * Created by michael on 17-8-7.
 */

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

/**
 * 文件夹类
 */
public class Folder extends File {

    private List<File> files;   //文件夹下的文件列表

    public Folder(String name) {
        super(name);
        this.files = new ArrayList<>();
    }

    @Override
    public void display() {

        for(File file : files) {
            file.display();
        }
    }

    /**
     * 向文件夹中添加文件
     * @param file
     */
    public void add(File file) {
        files.add(file);
    }

    /**
     * 从文件夹中删除文件
     * @param file
     */
    public void remove(File file) {
        files.remove(file);
    }
}

TextFile类、ImageFile类、VideoFile类:

package com.tao.pattern.composite;

/**
 * Created by michael on 17-8-7.
 */

/**
 * 文本文件
 */
public class TextFile extends File {

    public TextFile(String name) {
        super(name);
    }

    @Override
    public void display() {
        System.out.println("这是文本文件, 文件名:" + name);
    }
}
package com.tao.pattern.composite;

/**
 * Created by michael on 17-8-7.
 */

/**
 * 图像文件
 */
public class ImageFile extends File {

    public ImageFile(String name) {
        super(name);
    }

    @Override
    public void display() {
        System.out.println("这是图像文件, 文件名:" + name);
    }
}
package com.tao.pattern.composite;

/**
 * Created by michael on 17-8-7.
 */

/**
 * 视频文件
 */
public class VideoFIle extends File {

    public VideoFIle(String name) {
        super(name);
    }

    @Override
    public void display() {
        System.out.println("这是视频文件, 文件名:" + name);
    }
}

Client测试类:

package com.tao.pattern.composite;

/**
 * Created by michael on 17-8-7.
 */
public class Client {

    public static void main(String[] args) {

        //1) 首先建立文件系统(树型结构)
        Folder rootFolder = new Folder("根文件夹");
        //2) 向根文件夹添加三个文件和一个文件夹
        TextFile text1 = new TextFile("a.txt");
        ImageFile img1 = new ImageFile("b.jpg");
        VideoFIle video1 = new VideoFIle("c.rmvb");
        Folder childFolder = new Folder("childFolder");
        //3) 添加到根文件夹下面
        rootFolder.add(text1);
        rootFolder.add(img1);
        rootFolder.add(video1);
        rootFolder.add(childFolder);

        //4) 向childFolder中添加文件
        TextFile c_aText = new TextFile("c_a.txt");
        ImageFile c_bImage = new ImageFile("c_b.png");
        VideoFIle c_cVideo = new VideoFIle("c_c.mp4");
        childFolder.add(c_aText);
        childFolder.add(c_bImage);
        childFolder.add(c_cVideo);

        //5) 遍历rootFolder
        System.out.println("===========遍历rootFolder==========");
        rootFolder.display();

        //6) 遍历childFolder
        System.out.println("===========遍历childFolder==========");
        childFolder.display();

        //7) 删除c_b.png
        childFolder.remove(c_bImage);
        System.out.println("===========删除c_b.png之后==========");
        childFolder.display();

    }
}

结果:
这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值