结构型 组合模式
为什么需要组合模式
组合模式是把部分和整体(集合)的操作统一化,通常用于树形结构。例如:目录和文件,当大家都有数文件大小的时候可以考虑这种模式,会让代码显得很简洁。
实现
组合模式其实就是巧妙使用了递归,不同的类(实现同一个接口),在调用的时候采用同一种调用方法。例如这里打印路径。
go.mod
module composite
go 1.13
composite.go
package composite
import (
"bytes"
)
type filenode interface {
Print(sep string) string
}
type Dir struct {
name string
children []filenode
}
func NewDir(name string) *Dir {
return &Dir{name: name}
}
func (d *Dir) Add(node filenode) {
d.children = append(d.children, node)
}
func (d *Dir) Print(sep string) string {
var buf bytes.Buffer
buf.WriteString(d.name)
sep += sep
for _, node := range d.children {
// we can make use of the print here
buf.WriteString("\n")
buf.WriteString(sep + "|\n")
buf.WriteString(sep + "->")
buf.WriteString(node.Print(sep))
}
return buf.String()
}
type File struct {
name string
}
func NewFile(name string) *File {
return &File{
name: name,
}
}
func (f *File) Print(sep string) string {
return f.name
}
composite_test.go
package composite_test
import (
"composite"
"testing"
)
func TestComposite(t *testing.T) {
dir1 := composite.NewDir("dir1")
dir1.Add(composite.NewFile("file1"))
dir2 := composite.NewDir("dir2")
dir2.Add(composite.NewFile("file2"))
dir1.Add(dir2)
expectResult := `dir1
##|
##->file1
##|
##->dir2
####|
####->file2`
if dir1.Print("#") != expectResult {
t.Fatal(dir1.Print("#"))
}
}