组合模式介绍
组合模式属于结构型设计模式,可以使用这种设计模式将多个对象组合成树形结构,树中的每个对象都表示一个叶子结点,并且可以统一处理结构中的所有叶子结点。比如说,现在要统计一个企业中的总人数,首先要统计各个部门的人数,然后再将统计的结果求和得到公司的总人数,如下图所示:
上图中,公司部分和各个部门结点组成了树状结构,因为每个结点都是由对象组成,所以可以实现对整个树的统一处理,接下来就使用代码去实现。
组合模式示例代码
组合模式,包含一个可以统一处理所有对象的通用接口、一个表示结点中对象的类,以及一个实现了统一处理接口的具体类
创建一个所有对象的通用接口
代码语言:javascript复制java 代码解读复制代码/**
* 统计人数接口
*
*/
public interface NumberOfPeople {
//总人数
int count();
}
接口中包含一个代表单个部门人数的抽象方法
创建表示节点的类
代码语言:javascript复制java 代码解读复制代码/**
* 代表各个部门的类
*/
public class Department implements NumberOfPeople{
//部门人数
private int count;
//部门名称
private String name;
public Department(String name,int count) {
this.count = count;
this.name = name;
}
@Override
public int count() {
return count;
}
}
在这里,各个节点就是各个部门,所以创建一个表示部门的类,类中包含表示人数和部门名称的属性,count()
方法用来返回部门的人数。接下来,要创建树形结构的统一处理实现类。
创建统一处理实现类
代码语言:javascript复制java 代码解读复制代码/**
* 树的统一处理类
*/
public class CountImpl implements NumberOfPeople{
private List<NumberOfPeople> list = new ArrayList<>();
public void insert(NumberOfPeople param) {
list.add(param);
}
/**
* 求公司的总人数
*/
@Override
public int count() {
int count = list.stream().collect(Collectors.summingInt(v -> v.count()));
return count;
}
}
提示 统一处理实现类中,包含一个
List
集合,存放了所有的部门信息,因为组合模式是一个树结构,所以List
存放的对象也等于所有的子节点。在这个类中,包含一个insert
方法,用来将各个节点对象添加到集合中去,最后通过重写的count()
方法统一汇总各个节点中的部门人数。最终实现公司总人数的统计。
代码测试
代码语言:javascript复制java 代码解读复制代码public class test_01 {
public static void main(String[] args) {
CountImpl target = new CountImpl();
target.insert(new Department("IT部", 20));
target.insert(new Department("人事部", 3));
target.insert(new Department("销售部", 10));
int count = target.count();
System.out.println("公司总人数:" count);
}
}
运行结果:
通过组合模式的树形数据结构、树中结点的通用方法以及自定义的树结构统一处理方法,实现了公司总人数的统计。
总结
上面的示例代码,实现了统计一个公司的总人数,假如不使用这种设计模式,而是采用硬编码的办法去实现,无疑会增加代码的复杂度和代码的耦合。而采用组合模式,则可以先让各个组成部分通过通用的方法先去解决最小单位的问题,再通过统一的处理方法将各个节点的处理结果进行汇总,处理问题的方式更结构化。并且,组合模式的树形结构由各个节点组成,这些节点可以自由的添加或者删除,使得程序更易于扩展和维护。