组合模式(Composite Pattern)

容器与内容的一致性

1.基本介绍

该模式用于创造出像文件夹和文件这样的结构,使容器与内容具有一致性,创造出递归模式,就如同文件夹中可以存入文件,也可以存入文件夹,而查找的时候,都可以获得其条目名。


2.具体实现

类的一览表
在这里插入图片描述

类图
在这里插入图片描述

Entry类:

是一个制定规则的抽象类,定义了共有的方法.

/**
 * @author Jay
 * @date 2019/6/6 23:11
 * @description
 */
public abstract class Entry {
    public abstract String getName();

    public abstract int getSize();

    /**
     * 子类去调用此方法时会抛出异常,父类也可以不规定此方法,文件夹类独有方法,又构成组合关系.
     * @param entry
     * @return
     * @throws FileTreatmentException
     */
    public Entry add(Entry entry) throws FileTreatmentException {
        throw new FileTreatmentException();

    }
    /**
     * 重载方法,这样可以区别出第一次,也可以不必在父类中写,子类中自己判断输出结构.
     */
    public void printList() {
        // 显示条目
        printList("");
    }

    /**
     * 为一览加前缀
     * @param prefix
     */
    protected abstract void printList(String prefix);

    @Override
    public String toString() {

        return getName() + "(" + getSize() + ")";
    }
}

File类

/**
 * @author Jay
 * @date 2019/6/6 23:15
 * @description 普通文件类
 */
public class File extends Entry {
    private String name;
    private int size;

    public File(String name, int size) {
        super();
        this.name = name;
        this.size = size;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public int getSize() {

        return size;
    }

    @Override
    protected void printList(String prefix) {
        System.out.println(prefix + "/" + this);
    }
}

Directory类

/**
 * @author Jay
 * @date 2019/6/6 23:15
 * @description 文件夹类
 */
public class Directory extends Entry {
    private String name;

    /**
     * 只有文件夹才是数组结构,文件只是其中的元素,所以类型为directory
     * 而其中元素可以是文件,也可以是文件夹,所以泛型为父类泛型
     * 多个数组的套嵌结构,形成了文件树的结构形式.
     */
    private ArrayList<Entry> directory = new ArrayList<Entry>();

    public Directory(String name) {
        super();
        this.name = name;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public int getSize() { // 获取大小
        int size = 0;
        Iterator it = directory.iterator();

        while (it.hasNext()) {

            Entry entry = (Entry) it.next();
            // 获取长度
            size += entry.getSize();
        }
        return size;
    }

    /**
     * 重写了父类的添加方法.
     */
    @Override
    public Entry add(Entry entry) {
        directory.add(entry);
        return this;
    }

    @Override
    protected void printList(String prefix) { // 目录条目一览
        System.out.println(prefix + "/" + this);
        Iterator it = directory.iterator();
        while (it.hasNext()) {
            Entry entry = (Entry) it.next();
            // 递归调用,父类接收,判断向下转型,调用各自对应方法.
            entry.printList(prefix + "/" + name);
        }
    }
}

Main
测试类

/**
 * @author Jay
 * @date 2019/6/6 23:17
 * @description
 */
public class Main {
    public static void main(String[] args) {
        Directory dirRoot = new Directory("root");
        Directory dirUser = new Directory("user");
        Directory dirBin = new Directory("bin");
        Directory dirTmp = new Directory("tmp");

        dirRoot.add(dirBin);
        dirRoot.add(dirUser);
        dirRoot.add(dirTmp);
        dirBin.add(new File("bin1", 1024));

        Directory dirAdmin= new Directory("admin");
        dirUser.add(dirAdmin);
        dirUser.add(new File("admin1", 1024));
        dirRoot.printList();
    }
}

在这里插入图片描述

最终创建如同上图的文件树结构.


3.角色分析

Leaf(树叶)

表示内容,如同文件.

Composite(复合物)

表示容器的角色,可以放入leaf和compostie,如同文件夹.

Compontent

上述俩者的父类,定义共同的功能.

在这里插入图片描述


4.思考

该模式可以将容器与内容一致性.所以称为多个和单个的一致性,即将多个对象结合在一起,当作同一个对象处理.

Add方法的设计处理:

  • 在父类中,文件夹类重写,文件类调用会报错
  • 在父类中,不做任何行为,这样文件类调用不会发生任何变化
  • 可以在父类中声明,由子类具体实现.
  • 只定义在文件夹类中.这样向下转型就需要进行类型判断.
    此结构运用递归调用,遍历其中所有元素,所以,树结构都适用此模式.

To GitHub

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值