《Learn Data struct ures and Algorithms with Golang》作者: Bhagvan Kommadi
组合(Composite)
组合是在单个对象里的一组相似对象。对象用树的形式存储,以持久化整个层次结构。 组合模式 用来改变对象的层次结构集合。组合模式是以异构集合为模型的。新类型对象可以新增而不必改变接口和客户端代码。例如,你可以在web上的 UI 布局,目录树和管理跨部门员工上面使用组合模式。该模式提供一种用相似的方式访问单个对象和组的机制。
组合模式由component接口,component类,composite和客户端组成:
- component接口定义了所有对象的默认行为,和访问这个composite内组件的行为;
- composite和component类实现了component接口;
- 客户端与component接口交互来调用composite里的方法。
让我们假设存在一个带有perform方法的IComposite接口,还有一个实现此接口的Branch类,它有addLeaf,addBranch和perform方法。Leaflet类实现了带perform方法的IComposite接口。Branch类与leafs和branches是一对多的关系。递归的迭代分支,可以遍历这棵组合树,如下面代码所示:
//main package has examples shown
// in Hands-On Data Structures and algorithms with Go book
package main
// importing fmt package
import (
"fmt"
)
// IComposite interface
type IComposite interface {
perform()
}
// Leaflet struct
type Leaflet struct {
name string
}
// Leaflet class method perform
func (leaf *Leaflet) perform() {
fmt.Println("Leaflet " + leaf.name)
}
// Branch struct
type Branch struct {
leafs []Leaflet
name string
branches[]Branch
}
Branch类的perform方法调用branches和leafs上面的perform方法,正如代码所示:
// Branch class method perform
func (branch *Branch) perform() {
fmt.Println("Branch: " + branch.name)
for _, leaf := range branch.leafs {
leaf.perform()
}
for _, branch := range branch.branches {
branch.perform()
}
}
// Branch class method add leaflet
func (branch *Branch) add(leaf Leaflet) {
branch.leafs = append(branch.leafs, leaf)
}
如下面代码所示,Branch类的addBranch方法增加一个新的branch:
//Branch class method addBranch branch
func (branch *Branch) addBranch(newBranch Branch) {
branch.branches = append(branch.branches,newBranch)
}
//Branch class method getLeaflets
func (branch *Branch) getLeaflets() []Leaflet {
return branch.leafs
}
// main method
func main() {
var branch = &Branch{name:"branch 1"}
var leaf1 = Leaflet{name:"leaf 1"}
var leaf2 = Leaflet{name:"leaf 2"}
var branch2 = Branch{name:"branch 2"}
branch.add(leaf1)
branch.add(leaf2)
branch.addBranch(branch2)
branch.perform()
}
运行以下命令:
go run composite.go
让我们在下一节里看看装饰器模式。
装饰器(Decorator)
装饰器模式适用于移除或增加类职责的场景。当修改功能的时候,装饰器模式使用子类扩展,而不是静态继承。一个对象可能有多个装饰器和运行时装饰器。使用一个装饰器可以达到 单一职责原则 (single responsibility principle)。装饰器适用于窗口组件和图形化的对象模型。装饰器模式对于修改现存实例属性(attributes)与运行时增加新的方法都有帮助。
装饰器模式参与者是组件接口(component interface),具体组件类(concrete component),和装饰器类(decorator):
- 具体组件类实现了这个组件接口。
- 装饰器类实现这个组件接口并用相同的或者额外的方法提供额外的功能。这个装饰器基类可能是一个表示所有装饰器基类的参与者。
让我们假设IProcess是一个带有process方法的接口。ProcessClass实现带有process方法的接口。ProcessDecorator实现这个IProcess接口并拥有一个ProcessClass的实例。ProcessDecorator能增加更多的功能比ProcessClass,如下面代码所示:
//main package has examples shown
// in Hands-On Data Structures and algorithms with Go book
package main
// importing fmt package
import (
"fmt"
)
// IProcess Interface
type IProcess interface {
process()
}
//ProcessClass struct
type ProcessClass struct{}
//ProcessClass method process
func (process *ProcessClass) process() {
fmt.Println("ProcessClass process")
}
//ProcessDecorator struct
type ProcessDecorator struct {
processInstance *ProcessClass
}
在下面的代码里,ProcessDecorator类的process方法调用它的ProcessClass实例的process方法:
//ProcessDecorator class method process
func (decorator *ProcessDecorator) process() {
if decorator.processInstance == nil {
fmt.Println("ProcessDecorator process")
} else {
fmt.Printf("ProcessDecorator process and ")
decorator.processInstance.process()
}
}
//main method
func main() {
var process = &ProcessClass{}
var decorator = &ProcessDecorator{}
decorator.process()
decorator.processInstance = process
decorator.process()
}
运行下面的命令:
go run decorator.go
让我们在下一节看看门面模式。
下一篇:
上一篇: