Composite 设计模式?
在计算机的文件系统中, 有 "文件夹" 的概念 (在有些操作系统(Linux 操作系统) 中, 也称为 "目录"). 文件夹里面既可以放入文件, 也可以放入其他文件夹(子文件夹). 在子文件夹中, 一样地既可以放入文件, 也可以放入子文件夹. 可以说, 文件夹是形成了一种容器结构, 递归结构.
结构模式: 能够使容器与内容具有一致性, 创造出递归结构的模式就是 Composite 模式.
关注点: 使用 Composite 模式可以使容器与内容具有一致性, 也可以称其为多个和单个的一致性, 即将多个对象结合在一起, 当作一个对象进行处理.
理清职责
到处存在的递归结构:
在视窗系统中, 一个窗口可以含有一个子窗口,
2. 在文章的列表中, 各列表之间可以相互嵌套, 这也是一种递归结构.
3. 将多条计算机命令合并为一条宏命令时, 如果使用递归结构实现宏命.
4. 树结构的数据结构都适用 Composite 模式.
实现: 演示文件夹 文件子项之间的层次关系
名字 ===================>>>说明
Entry || 抽象类, 用来实现 File 类和 Directory 类的一致性
File || 表示文件的类
Directory || 表示文件夹的类
FileTreatementException || 表示向文件中增加 Entry 时发生的异常的类
Main || 测试程序行为的类
Add()方法的存在位置:
存在 Entry 抛出异常.
存在 Entry 中什么也不做.
声明在 Entry 中为抽象方法 不去实现.
直接定义在 Directory 类中, 但是需要关注类型之间的转换.
UML
类图:
- Code
- Entry
- ...
- public abstract class Entry {
- /**
- * 1. 文件名
- * 2. 文件大小
- * @return
- */
- public abstract String getName();
- public abstract int getSize();
- /**
- * Directory 增加条目
- * File 不能增加条目
- */
- public Entry add(Entry entry)throws FileTreatementException{
- throw new FileTreatementException();
- }
- public void printList(){
- printList("");
- }
- protected abstract void printList(String prefix);
- @Override
- public String toString() {
- return getName()+"("+getSize()+")";
- }
- }
- ...
- File
- public class File extends Entry {
- private String name;
- private int size;
- public File(String name, int size) {
- 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
- public class Directory extends Entry {
- private String name;
- private List<Entry> directory=new ArrayList<>();
- public Directory(String name) {
- this.name = name;
- }
- @Override
- public Entry add(Entry entry) throws FileTreatementException {
- directory.add(entry);
- return this;
- }
- @Override
- public String getName() {
- return name;
- }
- /**
- * getSize() | printList(String prefix)
- *
- * 都会递归去遍历下面可能存在的 目录或者文件的子项
- */
- @Override
- public int getSize() {
- int size=0;
- Iterator<Entry> it = directory.iterator();
- while (it.hasNext()){
- // 这里的 Entry 可能是目录 也可能是文件
- Entry next = it.next();
- size+=next.getSize();
- }
- return size;
- }
- @Override
- protected void printList(String prefix) {
- // 这里的 prefix 是一个引用 this 将会调用 tostring()方法 又会继续调用 getName() getSize()方法
- System.out.println(prefix+"/"+this);
- Iterator<Entry> it = directory.iterator();
- while(it.hasNext()){
- // 这里的 Entry 可能是目录 也可能是文件
- Entry next = it.next();
- next.printList(prefix+"/"+this);
- }
- }
- }
- FileTreatementException
- public class FileTreatementException extends Exception {
- public FileTreatementException() {
- }
- public FileTreatementException(String message) {
- super(message);
- }
- }
定义的目的结构:
- start +++++++++++
- /root(16000)
- /root(16000)/bin(16000)
- /root(16000)/bin(16000)/vi(1000)
- /root(16000)/bin(16000)/notepaid(15000)
- /root(16000)/temp(0)
- /root(16000)/user(0)
- MainT
- public class MainT {
- public static void main(String[] args) throws FileTreatementException{
- System.out.println("start +++++++++++");
- Directory rootdir=new Directory("root");
- Directory bindir = new Directory("bin");
- Directory tempdir = new Directory("temp");
- Directory userdir = new Directory("user");
- rootdir.add(bindir);
- rootdir.add(tempdir);
- rootdir.add(userdir);
- bindir.add(new File("vi",1000));
- bindir.add(new File("notepaid",15000));
- rootdir.printList();
- }
- }
来源: https://www.cnblogs.com/dgwblog/p/9840291.html