3 回答
TA贡献2019条经验 获得超9个赞
模板方法模式的本质是它允许您将一个或多个特定函数的实现注入到算法的骨架中。
你可以在 Go 中通过将函数或接口注入到你的Runner. 要实现基本的模板方法模式,您根本不需要您的Logger结构:
package main
import (
"fmt"
)
type Runner struct {
run func()
}
func (r *Runner) Start() {
// some prepare stuff...
r.run()
}
func runLog() {
fmt.Println("Running")
}
func NewLogger() *Runner {
return &Runner{runLog}
}
func main() {
l := NewLogger()
l.Start()
}
TA贡献1858条经验 获得超8个赞
Logger嵌入一个指针,当您分配结构时该指针将为 nil。这是因为嵌入不会将所有内容都放在结构中,它实际上创建了一个字段(在您的情况下以Runner类型命名*Runner),并且该语言为您提供了一些语法糖来访问其中的内容。在您的情况下,这意味着您可以通过Runner两种方式访问字段:
l := Logger{}
l.needStop = false
//or
l.Runner.needStop = false
要修复错误,您需要在Runner内部分配字段,Logger如下所示:
l := Logger{Runner:&Runner{}}
或者按值而不是指针嵌入。
TA贡献1794条经验 获得超8个赞
让模板方法设计模式在 Golang 中发挥作用的关键是正确使用嵌入特性和函数赋值。
下面是一个按预期工作的代码片段。
package main
import (
"fmt"
)
type Runner struct {
run func() // 1. this has to get assigned the actual implementation
}
func NewRunner(i func()) *Runner {
return &Runner{i}
}
func (r *Runner) Start() {
r.run()
}
type Logger struct {
Runner
}
func NewLogger() *Logger {
l := Logger{}
l.run = l.loggerRun // 2. the actual version is assigned
return &l
}
func (l *Logger) loggerRun() {
fmt.Println("Logger is running...")
}
func main() {
l := NewLogger() // 3. constructor should be used, to get the assignment working
l.Start()
}
Runner 类型func()根据特定的子类型定义了一个应该接收实际实现的属性。Start()包装对 的调用run(),并且一旦在正确的接收器(基础接收器)上调用,它就能够运行正确的版本run():如果在构造函数中发生这种情况(即NewLogger())方法的实际版本run()被分配给run嵌入的属性类型。
而且,输出是:
Logger is running...
Program exited.
在这里,可以运行代码并对其进行修改以测试此设计模式的任何其他变体。
- 3 回答
- 0 关注
- 173 浏览
添加回答
举报