设计模式-组合模式

组合模式

定义

组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。

这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。

类图

组合模式类图

Leaf(树叶)

表示“内容”的角色。在该角色中不能放入其他对象。

Composite(复合物)

表示容器的角色。可以在其中放入Leaf角色和Composite角色。

Component

使Leaf角色和Composite角色具有一致性的角色。Composite角色是Leaf角色和Composite角色的父亲。

Client

使用Composite模式的角色

示例

类图

组合模式示例类图

Entry

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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() + ")";
}
}

Directory

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
public class Directory extends Entry {

private String name;

private ArrayList<Entry> directory = new ArrayList<>();

public Directory(String name) {
// TODO Auto-generated constructor stub
this.name = name;
}

@Override
public String getName() {
// TODO Auto-generated method stub
return name;
}

@Override
public int getSize() {
int size = 0;
Iterator<Entry> it = directory.iterator();
while (it.hasNext()) {
Entry entry = it.next();
size += entry.getSize();
}

// TODO Auto-generated method stub
return size;
}

public Entry add(Entry entry) {
directory.add(entry);
return this;
}

@Override
protected void printList(String prefix) {
// TODO Auto-generated method stub
System.out.println(prefix + "/" + this);
Iterator<Entry> it = directory.iterator();
while (it.hasNext()) {
Entry entry = it.next();
entry.printList(prefix + "/" + name);
}
}

}

File

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
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() {
// TODO Auto-generated method stub
return name;
}

@Override
public int getSize() {
// TODO Auto-generated method stub
return size;
}

@Override
protected void printList(String prefix) {
// TODO Auto-generated method stub
System.out.println(prefix + "/" + this);
}

}

FileTreatmentException

1
2
3
4
5
6
7
8
9
10
11
12
public class FileTreatmentException extends RuntimeException {
private static final long serialVersionUID = 1L;

public FileTreatmentException() {

}

public FileTreatmentException(String msg) {
super(msg);
}
}

Main

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
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("user");

rootDir.add(binDir);
rootDir.add(tmpDir);
rootDir.add(userDir);
binDir.add(new File("vi", 10000));
binDir.add(new File("latex", 30000));

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("1.html", 100));
yuki.add(new File("2.html", 200));
hanako.add(new File("3.html", 300));
tomura.add(new File("4.html", 400));
tomura.add(new File("5.html", 500));

rootDir.printList();
} catch (FileTreatmentException e) {
e.printStackTrace();
}
}
}

0%