这一篇来说一说java设计模式之组合模式。

什么是组合模式呢?就是把对象组合成一个树状的层次结构。而且里面的对象具有相同的操作。 我不管我这个树里面是什么,他们都具有相似的操作,就具有相同的接口,自己不一样的放到自己的实现类里面,对外面都是一样的。 想到了什么? 没错,你没想错。就是 我们接下来看一看是不是。 (上面没有少打字) Linux里面,从根目录/开始,就是各种文件,文件夹,文件夹又嵌套文件/文件夹,很标准的树结构嘛。 我们都知道,不管文件(树叶节点)抑或文件夹(树枝节点),都具有相似的属性的,比如名称,比如创建时间,最多文件夹可以再放文件等。 这就很清晰了,有一个抽象的文档类,具有一些特定的属性,就是文件和文件夹的基类。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package top.txiner.composite;

/**
 * @author : hundred
 * time: 18-1-12
 * website : http://txiner.top
 * 懵懂的小白
 */
public abstract class Doc {
    private String name;
    private String createTime;

    public Doc(String name, String createTime) {
        this.name = name;
        this.createTime = createTime;
    }


    public void getInfo() {
        System.out.println("Doc{" +
                "name='" + name + '\'' +
                ", createTime='" + createTime + '\'' +
                '}');
    }
}

很简单的内容。然后文件夹结构,除了这个,还得允许添加结构,加入自己的文件或者文件夹。 除此之外,没什么需要改动的

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package top.txiner.composite;

import java.util.ArrayList;

/**
 * @author : hundred
 * time: 18-1-12
 * website : http://txiner.top
 * 懵懂的小白
 */
public class Folder extends Doc {

    private ArrayList<Doc> list=null;

    public Folder(String name, String createTime) {
        super(name, createTime);
        list=new ArrayList<>();
    }

    public void addDoc(Doc doc){
        this.list.add(doc);
    }

    public ArrayList<Doc> getList() {
        return list;
    }
}

文件就更简单了,除了基类的那些属性,它什么心都不用操,直接继承

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package top.txiner.composite;

/**
 * @author : hundred
 * time: 18-1-12
 * website : http://txiner.top
 * 懵懂的小白
 */
public class File extends Doc {
    public File(String name, String createTime) {
        super(name, createTime);
    }
}

很easy嘛!那我们试着构建个系统试试。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package top.txiner.composite;

import java.util.ArrayList;

/**
 * @author : hundred
 * time: 18-1-12
 * website : http://txiner.top
 * 懵懂的小白
 */
public class OperateSystem {
    public static void main(String[] args) {
        Folder root=new Folder("root","2006");
        Folder music=new Folder("music","2007");
        Folder image=new Folder("image","2007");
        Folder scenary=new Folder("scenary","2008");
        Folder animal=new Folder("animal","2009");
        Folder movie=new Folder("movie","2007");

        File Avengers=new File("Avengers","2009");
        File Wake=new File("Wake","2009");
        File Sky=new File("Sky","2009");
        File Panda=new File("Panda","2009");


        root.addDoc(music);
        root.addDoc(image);
        root.addDoc(movie);

        music.addDoc(Wake);
        movie.addDoc(Avengers);
        image.addDoc(scenary);
        image.addDoc(animal);
        scenary.addDoc(Sky);
        animal.addDoc(Panda);

        getTree(root);

    }


    public static void getTree(Folder folder){
        ArrayList<Doc> docs=folder.getList();
        for (Doc doc:docs){
            if (doc instanceof File){
                doc.getInfo();
            }else {
                doc.getInfo();
                getTree((Folder)doc);
            }
        }
    }
}

好了,建设完成了! 可以看到,组合模式不复杂嘛!

当然了,我们可以看到,我们也可以把addDoc放到基类Doc里面,让实现类做实现,文件类不操作就好。这样的放到基类的就是透明模式,不放的就是安全模式。 很容易看到哪个的特点了吧!