设计模式之组合模式
Posted ProChick
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式之组合模式相关的知识,希望对你有一定的参考价值。
1.简要概述
- 组合模式又叫做部分整体模式,它将对象组合成树形结构来表示“整体与部分”之间的层次关系。
- 组合模式使得用户对单个对象和组合对象的访问具有了一致性,即允许用户以统一的方式处理单个对象和组合对象。
- 组合模式为处理树形结构提供了完美的解决方案,描述了如何将容器和叶子进行递归组合,使得用户在使用时可以一致性的对待容器和叶子。
2.模式结构
👉通常由一个抽象组件接口(
负责定义所有实现类共有的方法接口
),多个具体的叶子实现类(在组合模式中,它表示叶子节点,没有子节点
),多个具体的组合实现类(负责管理组件对象,实现对象的相关操作
),一个客户类(负责调用抽象组件接口来对单独对象和组合对象进行统一处理
)共同组成。
3.实现代码
举例 💡 :假设我们现在要对学校这个组织进行管理,我们知道学校下面又可以分为多个院系,院系下面又分为多个专业,所以这可以理解为是一个树性结构(组织充当抽象组件、学校和院系充当组合对象、专业充当叶子对象
)。那么如果我们想要输出整个学校的院系专业信息,那么就可以使用组合模式进行处理。
组织类(抽象组件Component)
public abstract class Organization{
protected String name;
public Organization(String name){
this.name = name;
}
public void add(Organization organization){
//默认实现
}
public void remove(Organization organization){
//默认实现
}
public abstract void print();
}
学校类(组合对象Composite)
public class School extends Organization{
private List<Organization> childs = new ArraryList<Organization>();
public School(String name){
super(name);
}
@Override
public void add(Organization organization){
child.add(organization);
}
@Override
public void remove(Organization organization){
child.remove(organization);
}
@Override
public void print(){
System.out.println("****************" + name + "****************")
for (Organization organization : childs) {
System.out.println(organization.print());
}
}
}
学院类(组合对象Composite)
public class Academy extends Organization{
private List<Organization> childs = new ArraryList<Organization>();
public Academy(String name){
super(name);
}
@Override
public void add(Organization organization){
child.add(organization);
}
@Override
public void remove(Organization organization){
child.remove(organization);
}
@Override
public void print(){
System.out.println("----------------" + name + "----------------")
for (Organization organization : childs) {
System.out.println(organization.print());
}
}
}
专业类(叶子对象Leaf)
public class Speciality extends Organization{
public Speciality(String name){
super(name);
}
@Override
public void print(){
System.out.println(name);
}
}
客户类
// 测试客户端
public class OrganizationClient{
public static void main(String[] args) {
// 创建一个学校对象
Organization school = new School("北京大学");
// 为学校添加两个学院
Organization softwareAcademy = new Academy("软件学院");
Organization infoAcademy = new Academy("信息工程学院");
school.add(softwareAcademy);
school.add(infoAcademy);
// 为软件学院添加两个专业
Organization softwareSpeciality1 = new Speciality("软件工程");
Organization softwareSpeciality2 = new Speciality("网络工程");
softwareAcademy.add(softwareSpeciality1);
softwareAcademy.add(softwareSpeciality2);
// 为信息工程学院添加两个专业
Organization infoSpeciality1 = new Speciality("通信工程");
Organization infoSpeciality2 = new Speciality("信息工程");
infoAcademy.add(infoSpeciality1);
infoAcademy.add(infoSpeciality2);
// 打印该学校的所有学院和专业信息
school.print();
}
}
4.优点好处
- 简化了客户端的操作,客户端不必关心自己处理的是单个对象还是组合对象,不用考虑很复杂的结构问题。
- 提高了系统的扩展性,符合开闭原则,当我们想添加或移除某个组合对象或者叶子对象的时候,不用对原有的其它对象做任何修改,客户端也不用做任何改动。
- 提高了系统的可维护性,能够很容易的处理复杂的对象层次关系结构。
5.缺点弊端
- 由于在这种模式中,客户端需要对所有的组件实现类都能够做统一的操作,所以在增加新的组合对象时,没有办法对其进行一定的限制。
- 当系统的对象业务非常复杂的时候,组件抽象接口可能需要设置非常多的公共抽象方法,那么组合模式就会有很大的挑战性,因为在叶子对象中,无用的方法可能就会非常多。
6.应用场景
- 当系统中要处理的对象可以生成一颗树状结构,而我们要对树中的节点和叶子节点进行操作的时候使用,比如:文件结构管理。
- 当客户端想要使用统一的方式来处理部分对象和整体对象,也就是把部分和整体的关系用树形结构来表示的时候使用。
7.应用示例
JDK源码中的Map集合
通过上方代码我们可以看出,通过Map结构一样可以实现上面我们提到的输出学校组织结构信息的问题。
-
下面的Map接口就充当了抽象组件接口,内部封装了put()、putAll()等实现类的公共方法。
-
下面的HashMap类就充当了组合对象,实现了Map接口。
-
下面的Node内部类就充当了叶子对象,实现了Map接口。
所以通过分析可以看出Map集合的实现也利用到了组合模式
以上是关于设计模式之组合模式的主要内容,如果未能解决你的问题,请参考以下文章