GOF设计模式——Composite模式

一、什么是Composite模式?

        Composite模式,可以借助计算机文件夹的例子去理解,一个文件夹里面可以存放文件,也可以存放子文件夹,这样子形成一种结构,这个“文件夹”就类似于一个容器,而且还是一种具有递归结构的容器。我们可以用Composite模式创造出这样的结构,使得容器和内容具有一致性

二、Composite模式的原理

Client:使用Composite模式的相关类;

Leaf类:表示内容,可以是计算机系统文件夹里面的“文件”;

Composite类:表示容器,可以是计算机系统的文件夹,或者子文件夹;

Compenent类:这是一个抽象类,使得Leaf和Composite具有一致性的类;

三、Composite模式示例

1、Entry类:表示目录条目的抽象类,File类和Directory类是它的子类。

package com.cjs.composite;
 
public abstract class Entry {
    //获取名字
    public abstract String getName();
    //获取大小
    public abstract int getSize();
    //加入目录条目
    public Entry add(Entry entry) throws FileTreatMentException{
        throw new FileTreatMentException();
    }
 
    public void printList() {
        printList("");
    }
 
    protected abstract void printList(String prefix);
 
    public String toString() {
        return getName() + " (" + getSize() + ")";
    }
}

        目录条目与一个名字,可以通过getName方法获取这个名字,每一个条目都有一个大小,这个大小的值由getSize方法获取,另外还定义了一个add方法,用于添加子文件夹或者其他类型的文件。

2、File类:表示文件的类,继承Entry类,并实现父类Entry的抽象方法;

package com.cjs.composite;
 
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);
    }
}

3、Directory类:表示文件夹类,实现了父类Entry的抽象方法。

package com.cjs.composite;
 
import com.cjs.Strategy.Strategy;
 
import java.util.ArrayList;
import java.util.Iterator;
 
public class Directory extends Entry {
    private String name;//文件夹名字
    private ArrayList directory = new ArrayList();//文件夹中目录条目的集合
 
    public Directory(String name) {
        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
    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);
        }
    }
 
    //增加目录条目
    public Entry add(Entry entry) {
        directory.add(entry);
        return this;
    }
}

        因为是文件夹的类,所以定义了一个ArrayList类型的字段directory,用来保存文件夹中的目录条目,getSize方法则是用递归来计算其大小。

4、Main类

package com.cjs.composite;
 
import com.cjs.composite.Directory;
 
public class Main {
    public static void main(String[] args) {
        try {
            System.out.println("Making root entries...");
            Directory rootdir = new Directory("root");
            Directory bindir = new Directory("bin");
            Directory tmpdir = new Directory("tmp");
            Directory userdir = new Directory("usr");
            rootdir.add(bindir);
            rootdir.add(tmpdir);
            rootdir.add(userdir);
            bindir.add(new File("vi", 10000));
            bindir.add(new File("latex", 20000));
            rootdir.printList();
 
            System.out.println("");
            System.out.println("Making user entries...");
            Directory yuki = new Directory("yuki");
            Directory hanako = new Directory("hanako");
            Directory tomura = new Directory("tomura");
            userdir.add(yuki);
            userdir.add(hanako);
            userdir.add(tomura);
            yuki.add(new File("diary.html", 100));
            yuki.add(new File("memo.txt", 300));
            hanako.add(new File("composite.java", 200));
            tomura.add(new File("game.doc", 400));
            tomura.add(new File("junk.mail", 500));
            rootdir.printList();
        } catch (FileTreatMentException e) {
            e.printStackTrace();
        }
    }
}

预期文件夹层次结构:

输出结果:

posted @ 2019-02-18 16:50  KamShing  阅读(403)  评论(0编辑  收藏  举报