什么是组合模式?
- 组合模式即使容器和内容具有一致性,从而构建递归结构
- 将容器和内容当做同一种对象对待
示范代码(composite.go)
系统文件目录
package Composite
import "fmt"
// 一致性结构
type Entry interface {
getName() string
getSize() int
printList(prefix string)
}
// 文件
type File struct {
name string
size int
}
func NewFile(name string, size int) *File {
return &File{
name: name,
size: size,
}
}
func (f *File) getName() string {
return f.name
}
func (f *File) getSize() int {
return f.size
}
func (f *File) printList(prefix string) {
fmt.Printf("%s/%s\n", prefix, f.toString())
}
func (f *File) toString() string {
return fmt.Sprintf("%s (%d)", f.getName(), f.getSize())
}
// 文件夹
type Directory struct {
name string
Entrys []Entry
}
func NewDirectory(name string) *Directory {
return &Directory{
name: name,
}
}
func (d *Directory) getName() string {
return d.name
}
func (d *Directory) getSize() int {
sum := 0
for _, e := range d.Entrys {
sum += e.getSize()
}
return sum
}
func (d *Directory) add(entry Entry) {
d.Entrys = append(d.Entrys, entry)
}
func (d *Directory) printList(prefix string) {
fmt.Printf("%s/%s\n", prefix, d.toString())
for _, e := range d.Entrys {
e.printList(fmt.Sprintf("%s/%s", prefix, d.name))
}
}
func (d *Directory) toString() string {
return fmt.Sprintf("%s (%d)", d.getName(), d.getSize())
}
测试用例(composite_test.go)
package Composite
import (
"fmt"
"testing"
)
func TestEntry_PrintList(t *testing.T) {
fmt.Println("Making root entries...")
rootdir := NewDirectory("root")
bindir := NewDirectory("bin")
tmpdir := NewDirectory("tmp")
usrdir := NewDirectory("usr")
rootdir.add(bindir)
rootdir.add(tmpdir)
rootdir.add(usrdir)
bindir.add(NewFile("vi", 10000))
bindir.add(NewFile("latex", 20000))
rootdir.printList("")
fmt.Println("")
fmt.Println("Making user entries...")
yuki := NewDirectory("yuki")
hanako := NewDirectory("hanako")
tomura := NewDirectory("tomura")
usrdir.add(yuki)
usrdir.add(hanako)
usrdir.add(tomura)
yuki.add(NewFile("index.html", 100))
yuki.add(NewFile("Composite.md", 200))
hanako.add(NewFile("flag.text", 300))
tomura.add(NewFile("game.exe", 400))
tomura.add(NewFile("README.md", 500))
rootdir.printList("")
}