组合设计模式
创始人
2024-03-16 09:47:47
0

一、组合模式

1、定义

组合模式(Composite Pattern)又称作整体-部分(Part-Whole)模式,其宗旨是通过将单个对象(叶子节点)和组织对象(树枝节点)用相同的接口进行表示,使得客户对单个对象和组合对象的使用具有一致性,属于结构型设计模式。

2、结构

(1)模式的结构

主要角色如下:

  • 抽象组成角色(Component):单个对象和组织对象的抽象基类或者接口,表示整个树形结构中的对象都属于同一种类型,用于访问和管理子节点。
  • 组织对象角色(Composite):树枝节点,用来存储子节点,并实现了组织接口中的操作方法。
  • 单个对象角色(Left):叶子节点,它没有子节点,它不需要实现组织接口中的操作方法。

(2)组合模式有两种

  • 透明组合模式: 组织接口中声明用来管理子对象的所有行为方法,好处就是树枝节点和叶子节点对外界没有区别,它们具备完全一致的行为接口,缺点时,叶子节点本身不具备组织接口的行为方法,所以实现它们是没有意义的。
  • 安全组合模式: 组织接口中不声明用来管理子对象的所有行为方法,所以叶子节点也就不需要去实现它们。而是在组织节点中声明用来管理子对象的所有行为方法。这样做由于不够透明,树枝节点和叶子节点将不具有相同的接口,客户端的调用需要做相应的判断,带来了不便。

3、优缺点

优点:

  • 清楚地定义各层次的复杂对象,表示对象的全部或部分层次。
  • 让客户端忽略了层次的差异,方便对整个层次结构进行控制。
  • 符合开闭原则。

缺点:

  • 限制类型时会较为复杂。
  • 使设计变得更加抽象。

4、使用场景

  • 希望客户端可以忽略组个对象与单个对象的差异。
  • 对象层次具备整体和部分,呈树形结构。

5、在框架源码中使用

  • Java中 HashMap 的 putAll方法,存储使用了一个静态内部类的数据Node[]。
  • Mybatis源码中解析Mapping文件中的 SQL语句时,使用到的 SqlNode类的作用非常关键。

二、模式的通用实现

1、透明组合模式

代码如下:

public class CompositePattern1 {public static void main(String[] args) {Component1 root = new Composite1("root");Component1 branch1 = new Composite1("branch1");Component1 branch2 = new Composite1("branch2");Component1 leaf1 = new Leaf1("leaf1");Component1 leaf2 = new Leaf1("leaf2");Component1 leaf3 = new Leaf1("leaf3");Component1 leaf4 = new Leaf1("leaf4");root.addChild(branch1);root.addChild(leaf3);branch1.addChild(leaf1);branch1.addChild(branch2);branch2.addChild(leaf2);branch2.addChild(leaf4);String display = root.display();System.out.println(display);System.out.println("===============");System.out.println("branch2.getChild(1).display() -> " + branch2.getChild(1).display());branch2.removeChild(leaf4);String display2 = root.display();System.out.println(display2);}
}// 抽象组成角色
abstract class Component1 {protected String name;public Component1(String name) {this.name = name;}public abstract String display();public boolean addChild(Component1 component1) {throw new RuntimeException(" addChild 不支持");}public boolean removeChild(Component1 component1) {throw new RuntimeException(" removeChild 不支持");}public Component1 getChild(int index) {throw new RuntimeException(" getChild 不支持");}}// 组织对象角色
class Composite1 extends Component1 {private List component1List;public Composite1(String name) {super(name);this.component1List = new ArrayList();}@Overridepublic String display() {StringBuilder sb = new StringBuilder(this.name);for (int i = 0; i < component1List.size(); i++) {Component1 component1 = component1List.get(i);sb.append("\n");sb.append(component1.display());}return sb.toString();}@Overridepublic boolean addChild(Component1 component1) {return component1List.add(component1);}@Overridepublic boolean removeChild(Component1 component1) {return component1List.remove(component1);}@Overridepublic Component1 getChild(int index) {return component1List.get(index);}
}// 单个对象角色
class Leaf1 extends Component1 {public Leaf1(String name) {super(name);}@Overridepublic String display() {return this.name;}
}

在这里插入图片描述

2、安全组合模式

代码如下:

public class CompositePattern2 {public static void main(String[] args) {Composite2 root = new Composite2("root");Composite2 branch1 = new Composite2("branch1");Composite2 branch2 = new Composite2("branch2");Component2 leaf1 = new Leaf2("leaf1");Component2 leaf2 = new Leaf2("leaf2");Component2 leaf3 = new Leaf2("leaf3");Component2 leaf4 = new Leaf2("leaf4");root.addChild(branch1);root.addChild(leaf3);branch1.addChild(leaf1);branch1.addChild(branch2);branch2.addChild(leaf2);branch2.addChild(leaf4);String display = root.display();System.out.println(display);System.out.println("===============");System.out.println("branch2.getChild(1).display() -> " + branch2.getChild(1).display());branch2.removeChild(leaf4);String display2 = root.display();System.out.println(display2);}
}// 抽象组成角色
abstract class Component2 {protected String name;public Component2(String name) {this.name = name;}public abstract String display();}// 组织对象角色
class Composite2 extends Component2 {private List component2List;public Composite2(String name) {super(name);this.component2List = new ArrayList();}@Overridepublic String display() {StringBuilder sb = new StringBuilder(this.name);for (int i = 0; i < component2List.size(); i++) {sb.append("\n");Component2 component2 = component2List.get(i);sb.append(component2.display());}return sb.toString();}public boolean addChild(Component2 component2) {return component2List.add(component2);}public boolean removeChild(Component2 component2) {return component2List.remove(component2);}public Component2 getChild(int index) {return component2List.get(index);}
}// 单个对象角色
class Leaf2 extends Component2 {public Leaf2(String name) {super(name);}@Overridepublic String display() {return this.name;}
}

三、模式的应用实例

以文件系统为例,目录包含文件夹和文件。下面使用安全组合模式实现。

(1)目录:抽象组成角色

public abstract class Directory {protected String name;public Directory(String name) {this.name = name;}public abstract void show();
}

(2)文件夹:组织对象角色

public class Folder extends Directory {private List dirList;private Integer depth;public Folder(String name, Integer depth) {super(name);this.depth = depth;dirList = new ArrayList<>();}public void list() {for (Directory dir : this.dirList) {System.out.println(dir.name);}}@Overridepublic void show() {System.out.println(this.name);for (Directory dir : this.dirList) {if (this.depth != null) {for (Integer integer = 0; integer < this.depth; integer++) {System.out.print(" ");}for (Integer integer = 0; integer < this.depth; integer++) {if (integer == 0) {System.out.print("+");}System.out.print("-");}}dir.show();}}public boolean addChild(Directory directory) {return dirList.add(directory);}public boolean removeChild(Directory directory) {return dirList.remove(directory);}public Directory getChild(int index) {return dirList.get(index);}
}

(3)文件:单个对象角色

public class File extends Directory{public File(String name) {super(name);}@Overridepublic void show() {System.out.println(this.name);}
}

(4)测试

	public static void main(String[] args) {Folder root = new Folder("root", 1);File dy = new File("抖音.exe");File qq = new File("QQ.exe");root.addChild(dy);root.addChild(qq);Folder office = new Folder("办公软件", 2);File word = new File("Word.exe");File ppt = new File("PPT.exe");File excel = new File("Excel.exe");office.addChild(word);office.addChild(ppt);office.addChild(excel);Folder devTools = new Folder("开发工具", 3);File idea = new File("idea.exe");File navicat = new File("navicat.exe");devTools.addChild(idea);devTools.addChild(navicat);office.addChild(devTools);root.addChild(office);System.out.println("========show方法======");root.show();System.out.println("========list方法======");root.list();}

在这里插入图片描述

– 求知若饥,虚心若愚。

相关内容

热门资讯

文投控股股份有限公司关于累计诉... 本公司董事会及全体董事保证本公告内容不存在任何虚假记载、误导性陈述或者重大遗漏,并对其内容的真实性、...
新锦动力(300157)披露修... 截至2025年12月25日收盘,新锦动力(300157)报收于4.62元,较前一交易日上涨0.87%...
聚杰微纤(300819)披露制... 截至2025年12月25日收盘,聚杰微纤(300819)报收于28.81元,较前一交易日上涨3.0%...
康曼德资本董事长丁楹:A股将进... 2025年A股在政策、估值、盈利、资金四重支撑下走出了牛市行情,但市场细分赛道的分化却愈发明显。20...
缅甸妙瓦底KK园区等已被强力拆... 视频来源:公安部微信公众号 记者12月25日从公安部获悉,近日,公安部派出工作组会同缅甸、泰国执法部...
盐田港(000088)披露公司... 截至2025年12月25日收盘,盐田港(000088)报收于4.55元,较前一交易日上涨0.66%,...
952名缅甸妙瓦底地区涉电诈犯... 来源:人民日报客户端 中缅泰联合开展清剿缅甸妙瓦底地区 赌诈园区行动 952名缅甸妙瓦底地区涉电诈犯...