Нужна клёвая книга о паттернах на русском? Вот она »
Компоновщик

Компоновщик на Go

Компоновщик — это структурный паттерн, который позволяет создавать дерево объектов и работать с ним так же, как и с единичным объектом.

Компоновщик давно стал синонимом всех задач, связанных с построением дерева объектов. Все операции компоновщика основаны на рекурсии и «суммировании» результатов на ветвях дерева.

Концептуальный пример

Давайте попробуем понять паттерн Компоновщик, используя для примера файловую систему ОС. Внутри нее есть два типа объектов: файлы и папки. В некоторых случаях они должны восприниматься как одно и то же. Здесь нам пригодится паттерн проектирования Компоновщик.

Представьте, что вам нужно провести поиск по конкретному ключевому слову в вашей файловой системе. Такая операция поиска применяется в равной степени и к файлам, и к папкам. В случае файла, она только проверит содержимое файла, а в случае папки – обработает все файлы этой папки для нахождения ключевого слова.

file.go: Интерфейс компонента

package main

import "fmt"

type file struct {
	name string
}

func (f *file) search(keyword string) {
	fmt.Printf("Searching for keyword %s in file %s\n", keyword, f.name)
}

func (f *file) getName() string {
	return f.name
}

folder.go: Компоновщик

package main

import "fmt"

type folder struct {
	components []component
	name       string
}

func (f *folder) search(keyword string) {
	fmt.Printf("Serching recursively for keyword %s in folder %s\n", keyword, f.name)
	for _, composite := range f.components {
		composite.search(keyword)
	}
}

func (f *folder) add(c component) {
	f.components = append(f.components, c)
}

component.go: Лист

package main

type component interface {
	search(string)
}

main.go: Клиентский код

package main

func main() {
	file1 := &file{name: "File1"}
	file2 := &file{name: "File2"}
	file3 := &file{name: "File3"}

	folder1 := &folder{
		name: "Folder1",
	}

	folder1.add(file1)

	folder2 := &folder{
		name: "Folder2",
	}
	folder2.add(file2)
	folder2.add(file3)
	folder2.add(folder1)

	folder2.search("rose")
}

output.txt: Результат выполнения

Serching recursively for keyword rose in folder Folder2
Searching for keyword rose in file File2
Searching for keyword rose in file File3
Serching recursively for keyword rose in folder Folder1
Searching for keyword rose in file File1
По материалам: Golang By Example

Компоновщик на других языках программирования

Компоновщик на Java Компоновщик на C# Компоновщик на C++ Компоновщик на PHP Компоновщик на Python Компоновщик на Ruby Компоновщик на Swift Компоновщик на TypeScript