java设计模式-组合模式
组合模式
1、组合模式解决这样的问题,当我们的要处理的对象可以生成一颗树形结构,而我们要对树上的节点和叶子进行操作时,它能够提供一致的方式,而不用考虑它是节点还是叶子。
示意图如下
2、
原理结构图
@Data
public abstract class OrganizationComponent {
//名字
private String name;
//说明
private String description;
protected void add(OrganizationComponent organizationComponent) {
//默认实现
throw new UnsupportedOperationException();
}
protected void remove(OrganizationComponent organizationComponent) {
//默认实现
throw new UnsupportedOperationException();
}
//构造器
public OrganizationComponent(String name, String description) {
this.name = name;
this.description = description;
}
//方法打印 做成抽象的
protected abstract void print();
}
@Slf4j
public class University extends OrganizationComponent {
List<OrganizationComponent> organizationComponents = new ArrayList<OrganizationComponent>();
public University(String name, String description) {
super(name, description);
}
//重写
@Override
protected void add(OrganizationComponent organizationComponent) {
organizationComponents.add(organizationComponent);
}
//重写
@Override
protected void remove(OrganizationComponent organizationComponent) {
organizationComponents.remove(organizationComponent);
}
//重写
@Override
protected void print() {
log.info("================大学【{}】================", getName());
for (OrganizationComponent organizationComponent : organizationComponents) {
organizationComponent.print();
}
}
@Override
public String getName() {
return super.getName();
}
@Override
public String getDescription() {
return super.getDescription();
}
}
@Slf4j
public class College extends OrganizationComponent {
//List中存放的是department
List<OrganizationComponent> organizationComponents = new ArrayList<OrganizationComponent>();
public College(String name, String description) {
super(name, description);
}
//重写
@Override
protected void add(OrganizationComponent organizationComponent) {
//将来实际业务中,College的add方法和University的add方法不一定完全相同
organizationComponents.add(organizationComponent);
}
//重写
@Override
protected void remove(OrganizationComponent organizationComponent) {
organizationComponents.remove(organizationComponent);
}
//重写
@Override
protected void print() {
log.info("============学院:{}=============", getName());
for (OrganizationComponent organizationComponent : organizationComponents) {
organizationComponent.print();
}
}
@Override
public String getName() {
return super.getName();
}
@Override
public String getDescription() {
return super.getDescription();
}
}
@Slf4j
public class Department extends OrganizationComponent {
public Department(String name, String description) {
super(name, description);
}
//重写【add,remove都不用再写了,因为他是叶子结点】
@Override
protected void print() {
log.info("专业:{}", getName());
}
@Override
public String getName() {
return super.getName();
}
@Override
public String getDescription() {
return super.getDescription();
}
}
//============================
@Slf4j
public class Client {
public static void main(String[] args) {
//从大到小创建对象 学校
OrganizationComponent university = new University("清华大学", "中国顶级大学");
//创建学院
College computerCollege = new College("计算机学院", "计算机学院");
College infoEngineerCollege = new College("信息工程学院", "信息工程学院");
//创建各个学院下的专业
computerCollege.add(new Department("软件工程", "软件工程不错"));
computerCollege.add(new Department("网络工程", "网络工程不错"));
computerCollege.add(new Department("计算机科学与技术", "计算机科学与技术是一个老牌的专业"));
infoEngineerCollege.add(new Department("通信工程", "通信工程不好学"));
infoEngineerCollege.add(new Department("信息工程", "信息工程很好学"));
university.add(computerCollege);
university.add(infoEngineerCollege);
university.print();
}
}
- 打印
大学【清华大学】
学院:计算机学院=
==专业:软件工程
==专业:网络工程
==专业:计算机科学与技术
学院:信息工程学院=
==专业:通信工程
==专业:信息工程
总结
1、简化客户端操作。客户端只需要面对一致的对象而不用考虑整体部分或者节点叶子的问题。
2、具有较强的扩展性。当我们要更改组合对象时,我们只需要调整内部的层次关系,客户端不用做出任何改动。
3、方便创建出复杂的层次结构,客户端不用理会组合里面的组成细节,容易添加剂诶单或者叶子从而创建出复杂的树形结构。
4、需要遍历组织机构,或者处理的对象具有树形结构时,非常适合使用组合模式。
5、要求较高的抽象性,如果节点和叶子有很大的差异性的话,比如很多方法和树形都不一样,不适用于组合模式。
jdk的HashMap使用到了组合模式
public interface Map<K,V> {
//add remove
}
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
V value;
Node<K, V> next;
}
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable {
}