十、组合模式

组合模式(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)
}

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值