组合模式
说明
组合模式(Composite Pattern)属于结构型模式,是将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
在某些业务场景中,一个整体的各个组成部分是一种层级关系,一种树形结构。比如国家、省份、市级、区县这种结构,如果这种结构在程序中只是用简单的包含关系:国家类中包含省份集合,省份包含市级集合,那么只要这种组织结构一改,所有的代码都得调整。另外对于客户端来说,它们都是不同的类型,在对它们进行操作时需要进行区分。这时候就需要组合模式来解决该问题。
结构
组合模式的主要角色如下:
抽象根节点(Component):定义了组合中对象的共性;
树枝节点(Composite):定义了管理叶节点的容器及方法;
叶节点(Leaf):树形结构中具体的对象,实现在Component中定义的方法。
代码案例
组合模式有两种实现方式:透明方式、安全方式
透明方式
透明方式在抽象类或接口中定义了树枝类管理叶子对象的方法,所以叶子对象也会实现该方法
java
/**
* @program: composite
* @description: 抽象根节点(Component)
* @author: wxw
* @create: 2022-03-08 11:00
**/
public interface IComponent {
void add(IComponent component);
void remove(IComponent component);
void dispaly();
}
/**
* @program: composite
* @description: 树枝节点(Composite)
* @author: wxw
* @create: 2022-03-08 11:04
**/
@Getter
public class Composite implements IComponent {
private List<IComponent> items = new ArrayList<>();
private String name;
private Integer level;
public Composite(String name, Integer level) {
this.name = name;
this.level = level;
}
@Override
public void add(IComponent component) {
items.add(component);
}
@Override
public void remove(IComponent component) {
items.remove(component);
}
@Override
public void dispaly() {
System.out.println("【" + this.name + "】");
for (IComponent component : items){
if(this.level != null){
for (int i = 0; i < this.level; i++){
System.out.print(" ");
}
for (int i = 0; i < this.level; i++){
if (i == 0){
System.out.print("+");
}
System.out.print("-");
}
component.dispaly();
}
}
}
}
/**
* @program: composite
* @description: 叶节点(Leaf)
* @author: wxw
* @create: 2022-03-08 11:18
**/
public class Leaf implements IComponent {
private String name;
private String position;
public Leaf(String name, String position) {
this.name = name;
this.position = position;
}
@Override
public void add(IComponent component) {
throw new RuntimeException("叶节点不支持该操作!!!");
}
@Override
public void remove(IComponent component) {
throw new RuntimeException("叶节点不支持该操作!!!");
}
@Override
public void dispaly() {
System.out.println(this.name + ":" + this.position);
}
}
public class Test {
public static void main(String[] args) {
IComponent team = new Composite("开发团队", 3);
IComponent zhangsan = new Leaf("张三", "程序员");
IComponent lisi = new Leaf("李四", "项目经理");
team.add(zhangsan);
team.add(lisi);
IComponent dep = new Composite("华南部门", 2);
IComponent wangwu = new Leaf("王五", "部门总经理");
dep.add(wangwu);
dep.add(team);
IComponent root = new Composite("总公司", 1);
IComponent zhaoliu = new Leaf("赵六", "总裁");
root.add(zhaoliu);
root.add(dep);
root.dispaly();
}
}
输出结果:
bash
【总公司】
+-赵六:总裁
+-【华南部门】
+--王五:部门总经理
+--【开发团队】
+---张三:程序员
+---李四:项目经理
安全方式
安全方式只有树枝类定义了管理叶子类的方法,叶子类比较纯净,客户端使用时不能用抽象表示
java
/**
* @program: composite
* @description: 抽象根节点(Component)
* @author: wxw
* @create: 2022-03-08 11:00
**/
public interface IComponent {
void dispaly();
}
/**
* @program: composite
* @description: 树枝节点(Composite)
* @author: wxw
* @create: 2022-03-08 11:04
**/
@Getter
public class Composite implements IComponent {
private List<IComponent> items = new ArrayList<>();
private String name;
private Integer level;
public Composite(String name, Integer level) {
this.name = name;
this.level = level;
}
public void add(IComponent component) {
items.add(component);
}
public void remove(IComponent component) {
items.remove(component);
}
@Override
public void dispaly() {
System.out.println("【" + this.name + "】");
for (IComponent component : items){
if(this.level != null){
for (int i = 0; i < this.level; i++){
System.out.print(" ");
}
for (int i = 0; i < this.level; i++){
if (i == 0){
System.out.print("+");
}
System.out.print("-");
}
component.dispaly();
}
}
}
}
/**
* @program: composite
* @description: test
* @author: wxw
* @create: 2024-03-08 11:21
**/
public class Test {
public static void main(String[] args) {
Composite team = new Composite("开发团队", 3);
IComponent zhangsan = new Leaf("张三", "程序员");
IComponent lisi = new Leaf("李四", "项目经理");
team.add(zhangsan);
team.add(lisi);
Composite dep = new Composite("华南部门", 2);
IComponent wangwu = new Leaf("王五", "部门总经理");
dep.add(wangwu);
dep.add(team);
Composite root = new Composite("总公司", 1);
IComponent zhaoliu = new Leaf("赵六", "总裁");
root.add(zhaoliu);
root.add(dep);
root.dispaly();
}
}