【设计模式系列14】组合模式及其在JDK和MyBatis源码中的运用

本文详细介绍了组合模式的概念及其两种实现方式——透明组合模式和安全组合模式,并通过实例对比了两者之间的区别,最后总结了组合模式的角色、应用场景及优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

this.score = score;

}

@Override

public String getName(){

return this.name;

}

@Override

public void info() {

System.out.println(“课程:” + this.name + “,分数:” + score);

}

}

3、建立一个具有层级的节点,三个方法都重写了,支持添加子节点,这个类里面为了方便打印的时候看出层级关系,所以我定义了一个层级属性。

package com.zwx.design.pattern.composite.transparency;

import java.util.ArrayList;

import java.util.List;

/**

  • 树枝节点

*/

public class LevelCource extends GkAbstractCourse{

private List courseList = new ArrayList<>();

private String name;

private int level;

public LevelCource(String name, int level) {

this.name = name;

this.level = level;

}

@Override

public void addChild(GkAbstractCourse course) {

courseList.add(course);

}

@Override

public String getName(){

return this.name;

}

@Override

public void info() throws Exception {

System.out.println(“课程:” + this.name);

for (GkAbstractCourse course : courseList){

for (int i=0;i<level;i++){

System.out.print(" ");

}

System.out.print(">");

course.info();

}

}

}

4、建立一个测试类来测试一下:

package com.zwx.design.pattern.composite.transparency;

public class TestTransparency {

public static void main(String[] args) throws Exception {

GkAbstractCourse ywCourse = new CommonCource(“语文”,“150”);

GkAbstractCourse sxCourse = new CommonCource(“数学”,“150”);

GkAbstractCourse yyCourse = new CommonCource(“英语”,“150”);

GkAbstractCourse wlCourse = new CommonCource(“物理”,“110”);

GkAbstractCourse hxCourse = new CommonCource(“化学”,“100”);

GkAbstractCourse swCourse = new CommonCource(“生物”,“90”);

GkAbstractCourse lzCourse = new LevelCource(“理综”,2);

lzCourse.addChild(wlCourse);

lzCourse.addChild(hxCourse);

lzCourse.addChild(swCourse);

GkAbstractCourse gkCourse = new LevelCource(“理科高考科目”,1);

gkCourse.addChild(ywCourse);

gkCourse.addChild(sxCourse);

gkCourse.addChild(yyCourse);

gkCourse.addChild(lzCourse);

gkCourse.info();

}

}

输出结果:

课程:理科高考科目

课程:语文,分数:150

课程:数学,分数:150

课程:英语,分数:150

课程:理综

课程:物理,分数:110

课程:化学,分数:100

课程:生物,分数:90

这里如果用普通科目去调用add方法就会抛出异常,假如上面调用:

swCourse.addChild(ywCourse);

会输出

不支持添加操作

因为在普通科目类里面并没有重写addChild方法。

透明组合模式的缺陷


透明模式的特点就是将组合对象所有的公共方法都定义在了抽象组件内,这样做的好处是客户端无需分辨当前对象是属于树枝节点还是叶子节点,因为它们具备了完全一致的接口,不过缺点就是叶子节点得到到了一些不属于它的方法,比如上面的addChild方法,这违背了接口隔离性原则

安全组合模式


《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享

安全组合模式只是规定了系统各个层次的最基础的一致性行为,而把组合(树节点)本身的方法(如树枝节点管理子类的addChild等方法)放到自身当中。

1、首先还是建立一个顶层的抽象根节点(这里面只定义了一个通用的抽象info方法):

package com.zwx.design.pattern.composite.safe;

package com.zwx.design.pattern.composite.safe;

/**

  • 顶层抽象组件

*/

public abstract class GkAbstractCourse {

protected String name;

protected String score;

public GkAbstractCourse(String name, String score) {

this.name = name;

this.score = score;

}

public abstract void info();

}

2、建立一个叶子节点(这里只是重写了info方法,没有定义其他特有方法):

package com.zwx.design.pattern.composite.safe;

/**

  • 叶子节点

*/

public class CommonCource extends GkAbstractCourse {

public CommonCource(String name,String score) {

super(name,score);

}

@Override

public void info() {

System.out.println(“课程:” + this.name + “,分数:” + this.score);

}

}

3、定义一个树枝节点(这个类当中定义了一个树枝特有的方法addChild):

package com.zwx.design.pattern.composite.safe;

import java.util.ArrayList;

import java.util.List;

/**

  • 树枝节点

*/

public class LevelCource extends GkAbstractCourse{

private List courseList = new ArrayList<>();

private int level;

public LevelCource(String name, String score,int level) {

super(name,score);

this.level = level;

}

public void addChild(GkAbstractCourse course) {

courseList.add(course);

}

@Override

public void info() {

System.out.println(“课程:” + this.name + “,分数:” + this.score);

for (GkAbstractCourse course : courseList){

for (int i=0;i<level;i++){

System.out.print(" ");

}

System.out.print(">");

course.info();

}

}

}

4、新建测试类来测试:

package com.zwx.design.pattern.composite.safe;

public class TestSafe {

public static void main(String[] args) throws Exception {

CommonCource ywCourse = new CommonCource(“语文”,“150”);

CommonCource sxCourse = new CommonCource(“数学”,“150”);

CommonCource yyCourse = new CommonCource(“英语”,“150”);

CommonCource wlCourse = new CommonCource(“物理”,“110”);

CommonCource hxCourse = new CommonCource(“化学”,“100”);

CommonCource swCourse = new CommonCource(“生物”,“90”);

LevelCource lzCourse = new LevelCource(“理综”,“300”,2);

lzCourse.addChild(wlCourse);

lzCourse.addChild(hxCourse);

lzCourse.addChild(swCourse);

LevelCource gkCourse = new LevelCource(“理科高考”,“750”,1);

gkCourse.addChild(ywCourse);

gkCourse.addChild(sxCourse);

gkCourse.addChild(yyCourse);

gkCourse.addChild(lzCourse);

gkCourse.info();

}

}

输出结果为:

课程:理科高考,分数:750

课程:语文,分数:150

课程:数学,分数:150

课程:英语,分数:150

课程:理综,分数:300

课程:物理,分数:110

课程:化学,分数:100

课程:生物,分数:90

这里和透明方式不一样,叶子节点不具备addChild功能,所以无法调用,而上面的示例中时可以被调用,但是调用之后显示不支持,这就是这两种写法最大的区别。

组合模式角色

===================================================================

从上面示例中,可以看到组合模式包含了以下三个角色:

  • 抽象根节点(Component):定义系统各层次对象的公有属性和方法,可以预先定义一些默认行为和属性。

  • 树枝节点(Composite):定义树枝节点的行为,存储子节点,组合树枝节点和叶子节点形成一个树形结构。

  • 叶子节点(Leaf):是系统遍历层次中的最小单位,下面没有子节点。

组合模式在JDK源码中的体现

===========================================================================

  • 1、HashMap

HashMap中有一个putAll方法,参数是一个Map,这就是一种组合模式的体现:在这里插入图片描述

另外还有ArrayList中的addAll方法也是一样。

  • 2、MyBatis中有一个SqlNode接口,下面很多一级标签:在这里插入图片描述

然后一级标签下面又有二级标签(这就是组合模式的体现):

在这里插入图片描述

组合模式应用场景

=====================================================================

组合模式一般应用在有层级关系的场景,最经典的就是树形菜单,文件和文件夹的管理等

组合模式优缺点

====================================================================

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值