设计模式

组合模式(Composite)

2020-07-20  本文已影响0人  秀儿2020

定义

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

本质

统一叶子对象和组合对象

登场角色

示例代码

/**
 * 表示文件和文件夹的抽象类
 *
 * 叶子角色和复合物角色的父类
 */
public abstract class Dir {
    //声明一个List元素存储文件夹下的所有元素
    protected List<Dir> dirs = new ArrayList<>();
    private String name;//当前文件或者文件夹的名称
    public Dir(String name) {
        this.name = name;
    }
    //添加一个文件或者文件夹
    public abstract void addDir(Dir dir);
    //移除一个文件或者文件夹
    public abstract void removeDir(Dir dir);
    //清除文件夹下的所有元素
    public abstract void clear();
    //输入文件夹目录结构
    public abstract void print();
    //获取文件夹下所有的文件或者文件夹
    public abstract List<Dir> getFiles();
    //获取文件或者文件夹的名称
    
    public String getName() {
        return name;
    }
}


/**
 * 叶子角色
 */
public class File extends Dir{
    public File(String name) {
        super(name);
    }
    @Override
    public void addDir(Dir dir) {
        throw new UnsupportedOperationException("文件对象不支持该操作");
    }
    @Override
    public void removeDir(Dir dir) {
        throw new UnsupportedOperationException("文件对象不支持该操作");
    }
    @Override
    public void clear() {
        throw new UnsupportedOperationException("文件对象不支持该操作");
    }
    @Override
    public void print() {
        System.out.print(getName());
    }
    @Override
    public List<Dir> getFiles() {
        throw new UnsupportedOperationException("文件对象不支持该操作");
    }
}



/**
 * 复合角色
 */
public class Folder extends Dir{
    public Folder(String name) {
        super(name);
    }
    @Override
    public void addDir(Dir dir) {
        dirs.add(dir);
    }
    @Override
    public void removeDir(Dir dir) {
        dirs.remove(dir);
    }
    @Override
    public void clear() {
        dirs.clear();
    }
    @Override
    public void print() {
        System.out.print(getName() + "(");
        Iterator<Dir> iterator = dirs.iterator();
        while (iterator.hasNext()){
            Dir dir = iterator.next();
            dir.print();
            if(iterator.hasNext()){
                System.out.print(",");
            }
        }
        System.out.print(")");
    }
    @Override
    public List<Dir> getFiles() {
        return dirs;
    }
}



/**
 * 测试,使用组合模式的角色
 */
public class Client {
    public static void main(String[] args){
        //构造一个目录对象表示C盘根目录
        Dir diskC = new Folder("C盘");
        //C盘根目录下有一个文件
        diskC.addDir(new File("hello.txt"));
        //C盘根目录下还有三个子目录
        Dir windows = new Folder("Windows");
        diskC.addDir(windows);
        Dir logs = new Folder("Logs");
        diskC.addDir(logs);
        Dir users = new Folder("users");
        diskC.addDir(users);
        ///Windows目录下添加文件
        windows.addDir(new File("windows.txt"));
        //Logs目录下添加文件
        logs.addDir(new File("logs.txt"));
        //Users目录下添加文件
        users.addDir(new File("users.txt"));
        
        diskC.print();
    }
}

运行结果

C盘(hello.txt,Windows(windows.txt),Logs(logs.txt),users(users.txt))

功能

可以让使用者不用在区分叶子对象和组合对象,而是以一个统一的方式来调用。

优点

缺点

很难限制组件中的组件类型。

何时使用

上一篇下一篇

猜你喜欢

热点阅读