组合模式

将对象组合成树形结构以表示”部分-整体”的层次结构.
使用户对单个对象和组合对象的使用具有一致性.
组合模式定义了包含基本对象组合对象的类层次结构.基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合,这样不断的递归下去,客户代码中,任何用到基本对象的地方都可以使用组合对象.
用户不用关心到底是处理一个叶节点还是处理一个组合结点,也就用不着为定义组合而写一些选择判断语句了.简单说就是组合模式让客户可以一致性的使用组合结构和单个对象.

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
package composite;

/**
* Created by hero on 17-2-19.
*/
public abstract class Company {
private String name;

public Company(String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public abstract void add(Company c);
public abstract void remove(Company c);
public abstract void display(int depth);
public abstract void lineOfDuty(); //履行职责
}

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
package composite;

import java.util.LinkedList;
import java.util.List;

/**
* Created by hero on 17-2-19.
*/
public class ConcreteCompany extends Company {
private List<Company> children;

public ConcreteCompany(String name) {
super(name);
children = new LinkedList<Company>();
}

public void add(Company c) {
children.add(c);
}

public void remove(Company c) {
children.remove(c);
}

public void display(int depth) {
System.out.println(StringUtils.toStr('-', depth) + getName());
for (Company child : children) {
child.display(depth + 2);
}
}

public void lineOfDuty() {
for (Company child : children) {
child.lineOfDuty();
}
}
}

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 composite;

/**
* Created by hero on 17-2-19.
*/
public class FinanceDepartment extends Company {
public FinanceDepartment(String name) {
super(name);
}

public void add(Company c) {

}

public void remove(Company c) {

}

public void display(int depth) {
System.out.println(StringUtils.toStr('-', depth) + getName());
}

public void lineOfDuty() {
System.out.println(getName() + " 公司财务收支管理");
}
}

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 composite;

/**
* 人力资源部,相当于树叶
*/
public class HRDepartment extends Company {
public HRDepartment(String name) {
super(name);
}

public void add(Company c) {

}

public void remove(Company c) {

}

public void display(int depth) {
System.out.println(StringUtils.toStr('-', depth) + getName());
}

public void lineOfDuty() {
System.out.println(getName() + " 员工招聘培训管理");
}
}

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
package composite;

import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
* Created by hero on 17-2-19.
*/
public class StringUtils {
private static StringBuilder sb = new StringBuilder();
private static ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);

/**
* @param c
* @param num 字符c的个数
* @return 返回num个c的String
*/
public static String toStr(char c, int num) {
try {
lock.writeLock().lock();
sb.delete(0, sb.length());
for (int i = 0; i < num; i++) {
sb.append(c);
}
return sb.toString();
} finally {
lock.writeLock().unlock();
}
}

public static void main(String[] args) {
String str = toStr('a', 5);
System.out.println(str);
str = toStr('b', -2);
System.out.println(str);
}
}

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 composite;

/**
* Created by hero on 17-2-19.
*/
public class Main {
public static void main(String[] args) {
ConcreteCompany root = new ConcreteCompany("北京总公司");
root.add(new HRDepartment("总公司人力资源部"));
root.add(new FinanceDepartment("总公司财务部"));

ConcreteCompany comp = new ConcreteCompany("上海华东分公司");
comp.add(new HRDepartment("华东人力资源部"));
comp.add(new FinanceDepartment("华东财务部"));
root.add(comp);

ConcreteCompany comp2 = new ConcreteCompany("南京办事处");
comp2.add(new HRDepartment("南京人力资源部"));
comp2.add(new FinanceDepartment("南京财务部"));
comp.add(comp2);

root.display(1);

root.lineOfDuty();
}
}