当前位置: 首页 > article >正文

十、组合模式

组合模式(Composite Pattern)是一种结构型设计模式,它允许将对象组合成树形结构来表示“部分-整体”的层次关系。组合模式能够让客户端以统一的方式对待单个对象和对象集合,使得客户端在处理复杂树形结构的时候,可以以相同的方式对待单个对象和多个对象组合。

主要组成部分:

  1. 抽象组件(Component)

    • 定义了 leaf 和 composite 的对象共同实现的接口。在这里你可以定义接口的方法。
  2. 叶子(Leaf)

    • 实现了抽象组件,代表组合中的叶子节点。叶子节点没有子节点。
  3. 组合(Composite)

    • 也实现了抽象组件,代表可以有子节点的树节点。组合节点可以包含叶子或其他组合节点。
  4. 客户端(Client)

    • 使用组合结构的代码,通常通过接口与树结构交互。

优点:

  1. 一致性:客户端可以以一致的方式对待所有组成部分,无论是单个对象还是组合对象。
  2. 易于添加新组件:可以轻松地增加新的叶子或组合,无需修改现有代码。
  3. 简化客户端代码:客户端代码可以简单地使用组合结构,不需要关注部分和整体的区别。

使用场景:

  • 需要表示对象的树形结构。
  • 客户端希望以相同的方式处理单个对象和组合对象。
  • 需要在运行时增加或删除对象。

JAVA:

创建一个文件系统的结构

// 文件系统-抽象组件
public abstract class FileSystemComponent {

    protected String name; //名称

    //构造
    public FileSystemComponent(String name){
        this.name = name;
    }

    //抽象文件详情方法
    public abstract void showDetails();
}
// 叶子类-文件
public class File extends FileSystemComponent{

    public File(String name) {
        super(name);
    }

    @Override
    public void showDetails() {
        System.out.println("File: " + name);
    }
}
// 组合类
public class Folder extends FileSystemComponent{
    private List<FileSystemComponent> components = new ArrayList<>();

    public Folder(String name) {
        super(name);
    }

    // 添加文件/文件夹
    public void addComponent(FileSystemComponent component) {
        components.add(component);
    }

    // 删除文件
    public void removeComponent(FileSystemComponent component) {
        components.remove(component);
    }

    @Override
    public void showDetails() {
        System.out.println("Folder: " + name);
        for (FileSystemComponent component : components) {
            component.showDetails();
        }
    }
}
@Test(description = "组合模式")
    public void compositeTest(){
        // 创建文件和文件夹
        File file1 = new File("File1.txt");
        File file2 = new File("File2.txt");

        Folder folder1 = new Folder("Folder1");
        folder1.addComponent(file1);
        folder1.addComponent(file2);

        File file3 = new File("File3.txt");
        Folder folder2 = new Folder("Folder2");
        folder2.addComponent(file3);

        // 创建根文件夹
        Folder rootFolder = new Folder("RootFolder");
        rootFolder.addComponent(folder1);
        rootFolder.addComponent(folder2);

        // 显示文件夹结构
        rootFolder.showDetails();
    }

GO:

公司的人员组织就是一个典型的树状的结构,现在假设我们现在有部分,和员工,两种角色,一个部门下面可以存在子部门和员工,员工下面不能再包含其他节点。
我们现在要实现一个统计一个部门下员工数量的功能

package composite

// IOrganization 组织接口,都实现统计人数的功能
type IOrganization interface {
	Count() int
}

// Employee 员工
type Employee struct {
	Name string
}

// Count 统计人数
func (e Employee) Count() int {
	return 1
}

// Department 部门
type Department struct {
	Name             string
	SubOrganizations []IOrganization
}

// Count 人数统计
func (d Department) Count() int {
	c := 0
	for _, org := range d.SubOrganizations {
		c += org.Count()
	}
	return c
}

// AddSub 添加子节点
func (d *Department) AddSub(o IOrganization) {
	d.SubOrganizations = append(d.SubOrganizations, o)
}

// NewOrganization 构建组织架构 demo
func NewOrganization() IOrganization {
	root := &Department{Name: "root"}
	for i := 0; i < 10; i++ {
		root.AddSub(&Employee{})
		root.AddSub(&Department{Name: "sub", SubOrganizations: []IOrganization{&Employee{}}})
	}
	return root
}
package composite

import (
	"github.com/stretchr/testify/assert"
	"testing"
)

func TestComposite(t *testing.T) {
	got := NewOrganization().Count()
	assert.Equal(t, 20, got)
}


http://www.kler.cn/a/301657.html

相关文章:

  • 大模型论文精华-AI在医疗诊断、语言学习与情绪识别等领域的最新应用进展
  • web——upload-labs——第三关——后缀黑名单绕过
  • 若点集A=B则A必能恒等变换地变为B=A这一几何常识推翻直线(平面)公理
  • Python爬虫项目 | 一、网易云音乐热歌榜歌曲
  • 工作时发现自己手写SQL能力很低,特此再来学习一遍SQL
  • Rust学习(五):泛型、trait
  • AcWing119 袭击
  • 韩语中的多义词 (치다)柯桥学韩语到蓝天广场附近
  • Python的学习(三十二)---- ctypes库的使用整理
  • LSP协议:打造流动性管理的市场新标杆
  • [前端][js]获取当前正在执行的Javascript脚本文件的路径
  • 项目实现:云备份(一)
  • 【数字集成电路与系统设计】一些Chisel语法的介绍
  • 二、Maven工程的创建--JavaSEJavaEE
  • Element UI按钮组件:构建响应式用户界面的秘诀
  • vue3 ref
  • ffmpeg7.0 AVFrame的分配与释放
  • 使用 DBeaver 创建 MySQL 数据库
  • 第十五届蓝桥杯图形化省赛题目及解析
  • 前端 PDF 预览技巧:标签 vs 插件,如何优雅地展示 PDF 文件
  • 6、多线程
  • 如何使用python运行Flask开发框架并实现无公网IP远程访问
  • 力扣刷题之2555.两个线段获得的最多奖品
  • 装杯 之 Linux 指令1
  • 哈希表及算法
  • xLSTM模型学习笔记