原创文章,转载请务必将下面这段话置于文章开头处(保留超链接)。
本文转发自技术世界,原文链接 http://www.jasongj.com/design_pattern/composite/
组合模式介绍
组合模式定义
组合模式(Composite Pattern)将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户可以使用一致的方法操作单个对象和组合对象。
组合模式类图
组合模式类图如下
组合模式角色划分
抽象组件,如上图中的Component
简单组件,如上图中的SimpleComponent
复合组件,如上图中的CompositeComponent
组合模式实例
实例介绍
对于一家大型公司,每当公司高层有重要事项需要通知到总部每个部门以及分公司的各个部门时,并不希望逐一通知,而只希望通过总部各部门及分公司,再由分公司通知其所有部门。这样,对于总公司而言,不需要关心通知的是总部的部门还是分公司。
实例类图
组合模式实例类图如下(点击可查看大图)
实例解析
本例代码可从作者Github下载
抽象组件
抽象组件定义了组件的通知接口,并实现了增删子组件及获取所有子组件的方法。同时重写了hashCode
和equales
方法(至于原因,请读者自行思考。如有疑问,请在评论区留言)。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
47package com.jasongj.organization;
import java.util.ArrayList;
import java.util.List;
public abstract class Organization {
private List<Organization> childOrgs = new ArrayList<Organization>();
private String name;
public Organization(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void addOrg(Organization org) {
childOrgs.add(org);
}
public void removeOrg(Organization org) {
childOrgs.remove(org);
}
public List<Organization> getAllOrgs() {
return childOrgs;
}
public abstract void inform(String info);
public int hashCode(){
return this.name.hashCode();
}
public boolean equals(Object org){
if(!(org instanceof Organization)) {
return false;
}
return this.name.equals(((Organization) org).name);
}
}
简单组件(部门)
简单组件在通知方法中只负责对接收到消息作出响应。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18package com.jasongj.organization;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Department extends Organization{
public Department(String name) {
super(name);
}
private static Logger LOGGER = LoggerFactory.getLogger(Department.class);
public void inform(String info){
LOGGER.info("{}-{}", info, getName());
}
}
复合组件(公司)
复合组件在自身对消息作出响应后,还须通知其下所有子组件1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22package com.jasongj.organization;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Company extends Organization{
private static Logger LOGGER = LoggerFactory.getLogger(Company.class);
public Company(String name) {
super(name);
}
public void inform(String info){
LOGGER.info("{}-{}", info, getName());
List<Organization> allOrgs = getAllOrgs();
allOrgs.forEach(org -> org.inform(info+"-"));
}
}