文章目录
- [十、composite 组合模式](#十、composite 组合模式)
-
- [10.1 search_in_file_folder](#10.1 search_in_file_folder)
-
- [10.1.1 inode_test.go](#10.1.1 inode_test.go)
- [10.1.2 inode.go](#10.1.2 inode.go)
- [10.1.3 file.go](#10.1.3 file.go)
- [10.1.4 folder.go](#10.1.4 folder.go)
十、composite 组合模式
https://refactoringguru.cn/design-patterns/composite
树状结构, 适合用组合模式, 不断递归, 对各子节点求和, 直到叶子节点为止.
例如, 一个大盒子, 内可以放置物体, 或若干小盒子. 而每个小盒子又同理.
10.1 search_in_file_folder
https://refactoringguru.cn/design-patterns/composite/go/example
希望在一个目录中搜索文件名
目录中有子目录和文件, 这是一个树状结构, 需要递归计算
bash
10composite/101search_in_file_folder
├── file.go
├── folder.go
├── inode.go
├── inode_test.go
└── readme.md
10.1.1 inode_test.go
go
package _01search_in_file_folder
import (
"github.com/stretchr/testify/require"
"testing"
)
func TestExistInTree(t *testing.T) {
f1 := &file{name: "f1"}
f2 := &file{name: "f2"}
f3 := &file{name: "f3"}
d1 := &folder{name: "d1", children: []iNode{f1, f2}}
d2 := &folder{name: "d2", children: []iNode{f3}}
d := &folder{name: "d3", children: []iNode{d1, d2}}
require.True(t, d.ExistInTree("f1"))
require.True(t, d.ExistInTree("f2"))
require.True(t, d.ExistInTree("f3"))
require.True(t, d.ExistInTree("d1"))
require.True(t, d.ExistInTree("d2"))
require.True(t, d.ExistInTree("d3"))
require.False(t, d.ExistInTree("a"))
require.False(t, d.ExistInTree(""))
}
10.1.2 inode.go
go
package _01search_in_file_folder
type iNode interface {
Name() string
ExistInTree(query string) bool
}
10.1.3 file.go
go
package _01search_in_file_folder
type file struct {
name string
}
func (f *file) Name() string {
return f.name
}
func (f *file) ExistInTree(query string) bool {
return f.Name() == query
}
10.1.4 folder.go
go
package _01search_in_file_folder
type folder struct {
name string
children []iNode
}
func (f *folder) Name() string {
return f.name
}
func (f *folder) ExistInTree(query string) bool {
if f.Name() == query {
return true
}
for _, child := range f.children {
exist := child.ExistInTree(query)
if exist {
return true
}
}
return false
}