设计模式之组合模式案例详解
基本介绍
组合模式,又叫部分整体模式,它创建了对象组的树形结构,将对象组合成树状结构以表示“整体-部分”的层次关系。
组合模式依据树形结构来组合对象,用来表示部分以及整体层次。
这种类型的设计模式属于结构性模式。
组合模式使得用户对单个对象和组合对象的访问具有一致性,即:组合能让客户以一致的方式处理个别对象以及组合对象。
组合模式原理类图:
- Component:这是组合中对象声明接口,在适当情况下,实现所有类共有的接口默认行为,用于访问和管理Component子部件,Component可以是抽象类或接口。
- Leaf:在组合中表示叶子节点,叶子节点没有子节点。
- Composite:非叶子节点,用于存储子部件,在Component接口中实现子部件的相关操作,比如增加、删除。
传统方式
案例
编写程序展示一个学校院系结构,需求是这样的:要在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系。如图:
传统方案解决学校院系展示
分析:
- 将学院看作是学校的子类,系是学院的子类,这样实际上是站在组织大小来进行分层次的。
- 实际上我们的要求是:在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系,因此这种方案,不能很好地实现管理的操作,比如对学院、系的添加、删除、遍历等。
- 解决方案:把学校、院、系都看作是组织结构 ,他们之间没有继承的关系,而是一个树形结构,可以更好的实现管理操作(组合模式)
组合模式
思路分析
代码实现
1public abstract class OrganizationComponent {
2
3 private String name;//名字
4
5 private String des;//描述
6
7 public OrganizationComponent(String name, String des) {
8 this.name = name;
9 this.des = des;
10 }
11
12 protected void add(OrganizationComponent organizationComponent) {
13 //默认实现
14 throw new UnsupportedOperationException();
15 }
16
17 protected void remove(OrganizationComponent organizationComponent) {
18 //默认实现
19 throw new UnsupportedOperationException();
20 }
21
22 protected abstract void print();
23
24
25 public String getName() {
26 return name;
27 }
28
29 public void setName(String name) {
30 this.name = name;
31 }
32
33 public String getDes() {
34 return des;
35 }
36
37 public void setDes(String des) {
38 this.des = des;
39 }
40}
1//University就是 Composite,可以管理College
2public class University extends OrganizationComponent {
3
4 List<OrganizationComponent> organizationComponents = new ArrayList<OrganizationComponent>();
5
6 public University(String name, String des) {
7 super(name, des);
8 }
9
10 @Override//重写
11 protected void add(OrganizationComponent organizationComponent) {
12 organizationComponents.add(organizationComponent);
13 }
14
15 @Override//重写
16 protected void remove(OrganizationComponent organizationComponent) {
17 organizationComponents.remove(organizationComponent);
18 }
19
20 @Override//重写
21 public String getName() {
22 return super.getName();
23 }
24
25 @Override//重写
26 public String getDes() {
27 return super.getDes();
28 }
29
30 @Override
31 protected void print() {
32 System.out.println("---------------" + getName() + "-------------------");
33 for (OrganizationComponent organizationComponent : organizationComponents) {
34 organizationComponent.print();
35 }
36 }
37}
1public class College extends OrganizationComponent {
2
3 List<OrganizationComponent> organizationComponents = new ArrayList<OrganizationComponent>();
4
5 public College(String name, String des) {
6 super(name, des);
7 }
8
9 @Override//重写
10 protected void add(OrganizationComponent organizationComponent) {
11 organizationComponents.add(organizationComponent);
12 }
13
14 @Override//重写
15 protected void remove(OrganizationComponent organizationComponent) {
16 organizationComponents.remove(organizationComponent);
17 }
18
19 @Override//重写
20 public String getName() {
21 return super.getName();
22 }
23
24 @Override//重写
25 public String getDes() {
26 return super.getDes();
27 }
28
29 @Override
30 protected void print() {
31 System.out.println("---------------" + getName() + "-------------------");
32 for (OrganizationComponent organizationComponent : organizationComponents) {
33 organizationComponent.print();
34 }
35 }
36}
1public class Depatment extends OrganizationComponent {
2
3 public Depatment(String name, String des) {
4 super(name, des);
5 }
6
7 @Override
8 protected void print() {
9 System.out.println(getName());
10 }
11
12 //add、remove不需要写了,因为它是叶子节点,不需要管理其他节点
13
14 @Override
15 public String getDes() {
16 return super.getDes();
17 }
18
19 @Override
20 public String getName() {
21 return super.getName();
22 }
23}
1public class Client {
2 public static void main(String[] args) {
3
4 //从大到小创建对象,学校
5 OrganizationComponent university = new University("清华大学", "顶级大学");
6
7 //学院
8 OrganizationComponent college1 = new College("计算机学院", "计算机学院");
9 OrganizationComponent college2 = new College("信息工程学院", "信息工程学院");
10
11 //专业
12 college1.add(new Depatment("软件工程", "软件工程"));
13 college1.add(new Depatment("网络工程", "网络工程"));
14 college2.add(new Depatment("通信工程", "通信工程"));
15 college2.add(new Depatment("信息工程", "信息工程"));
16
17 //将学院加入到学校
18 university.add(college1);
19 university.add(college2);
20
21 university.print();
22 college1.print();
23
24 }
25}
注意事项
简化客户端操作。客户端只需要面对一致的对象而不用考虑整体部分或者节点叶子的问题。
具有较强的扩展性。当我们要更改组合对象时,我们只需要调整内部的层次关系,客户端不用做出任何改动。
方便创建出复杂的层次结构。客户端不用理会组合里面的组成细节,容易添加节点或者叶子从而创建出复杂的树形结构。
需要遍历组织机构,或者处理的对象具有树形结构时,非常适合使用组合模式。
要求较高的抽象性,如果节点和叶子有很多差异性的话,比如很多方法和属性都不一样,不适合使用组合模式。
作者:-亚州Asu-
若标题中有“转载”字样,则本文版权归原作者所有。若无转载字样,本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
tips:你的点赞我都当成了喜欢~