组合模式(Composite Pattern)又叫部分整体模式,是一种结构型模式,其依据树形结构来组合对象,用来表示部分以及整体之间的层次关系。
组合模式使得用户对单个对象和组合对象的访问具有一致性,即组合能让客户以一致的方式处理个别对象以及组合对象。下面我们来看个具体的例子。
1、学校院系展示需求
需求:编写程序展示一个学校院系结构,要求在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系。
最直接的,一个继承走天下。将学院看做是学校的子类,系是学院的子类,这样是站在组织大小来进行划分层次,并不能很好实现管理的操作。
通过使用组合模式,我们将学校、院、系都看成是组织结构,它们之间没有继承关系,而是一个树形结构,可以更好的实现管理操作。
2、组合模式解决问题
首先看下组合模式的原理图,其主要包含三个角色:
Component:这是组合中对象声明接口,一般用来实现所有类共有的接口默认行为,用于访问和管理Component子部件,可以是抽象类或接口
Leaf:在组合中表示叶子节点,叶子节点没有子节点
Composite:非叶子节点,用于存储子部件,实现Component接口中子部件的相关操作。
对于上面的需求,采用组合模式的类图如下,通过指向父类的引用实现组织之间的管理:
Component抽象类:
public abstract class OrganizationComponent {
private String name;//名字
private String des;//说明
//构造器
public OrganizationComponent(String name, String des) {
this.name = name;
this.des = des;
}
//共有方法
protected void add(OrganizationComponent organizationComponent){
//默认实现
throw new UnsupportedOperationException();
}
protected void remove(OrganizationComponent organizationComponent){
throw new UnsupportedOperationException();
}
//做成抽象,子类都需要实现
protected abstract void print();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDes() {
return des;
}
public void setDes(String des) {
this.des = des;
}
}
非叶子节点实现:
class University extends OrganizationComponent{
List<OrganizationComponent> organizationComponents=new ArrayList<>();
public University(String name, String des) {
super(name, des);
}
@Override
protected void add(OrganizationComponent organizationComponent) {
organizationComponents.add(organizationComponent);
}
@Override
protected void remove(OrganizationComponent organizationComponent) {
organizationComponents.remove(organizationComponent);
}
@Override
public String getName() {
return super.getName();
}
@Override
public String getDes() {
return super.getDes();
}
@Override
protected void print() {
System.out.println("==============="+getName()+"=================");
for (OrganizationComponent og: organizationComponents) {
og.print();
}
}
}
class College extends OrganizationComponent{
List<OrganizationComponent> organizationComponents=new ArrayList<>();
public College(String name, String des) {
super(name, des);
}
@Override
protected void add(OrganizationComponent organizationComponent) {
organizationComponents.add(organizationComponent);
}
@Override
protected void remove(OrganizationComponent organizationComponent) {
organizationComponents.remove(organizationComponent);
}
@Override
public String getName() {
return super.getName();
}
@Override
public String getDes() {
return super.getDes();
}
@Override
protected void print() {
System.out.println("==============="+getName()+"=================");
for (OrganizationComponent og: organizationComponents) {
og.print();
}
}
}
叶子节点实现:
class Department extends OrganizationComponent{
public Department(String name, String des) {
super(name, des);
}
@Override
public String getName() {
return super.getName();
}
@Override
public String getDes() {
return super.getDes();
}
@Override
protected void print() {
System.out.println(getName());
}
}
客户端
public class Client {
public static void main(String[] args) {
//从大到小创建对象 学校
University university = new University("家里蹲大学", "家家");
//创建学院
OrganizationComponent comYuan = new College("计算机学院", "学计算机");
OrganizationComponent XINYuan = new College("信息学院", "搞信息");
//加专业
comYuan.add(new Department("计算机", "好"));
comYuan.add(new Department("网络工程","有意思"));
XINYuan.add(new Department("通信工程","通信的"));
XINYuan.add(new Department("信息","难学"));
university.add(comYuan);
university.add(XINYuan);
// university.print();
comYuan.print();
}
}
3、总结
组合模式简化了客户端的操作,客户端只需要面对一致的对象而不用考虑整体部分或者节点叶子的问题
具有较强的扩展性,当需要更改组合对象时,只需要调整内部的层次关系,客户端不用做出任何改动
当需要遍历组织机构,或者处理的对象具有树形结构时,非常适用组合模式。但是如果节点和叶子有很多差异性的话,则不适用组合模式
推荐阅读
设计模式七大原则
UML类图的六大关系
八种单例模式分析
由浅入深工厂模式
原型模式及深浅拷贝详解
建造者模式
适配器设计模式
桥接模式
装饰者模式
网友评论