我的经验是使用 OOP 语言,但我已经开始尝试使用 Go。我无法找到实现 Observer design pattern 的最佳方法在围棋中。
我按如下方式组织了我的项目,其中 observers
文件夹中的所有内容都是 package observers
的一部分,而 subjects
文件夹中的所有内容都是包主题
的一部分。将观察者附加到主题是在 main.go
中完成的。
my-project/
main.go
observers/
observer.go
observer_one.go
observer_two.go
subjects/
subject.go
subject_one.go
我看过 this section in the Go wiki关于接口(interface):
Go interfaces generally belong in the package that uses values of the interface type, not the package that implements those values. The implementing package should return concrete (usually pointer or struct) types: that way, new methods can be added to implementations without requiring extensive refactoring.
牢记来自 Go Wiki 的评论。我是这样实现的(省略了函数实现):
主题.go:
type ObserverInterface interface {
Update(subject *Subject, updateType string)
}
type Subject struct {
observers map[string][]ObserverInterface
}
func (s *Subject) Attach(observer ObserverInterface, updateType string) {}
func (s *Subject) Detach(observer ObserverInterface, updateType string) {}
func (s *Subject) notify(updateType string) {}
观察者.go:
type SubjectInterface interface {
Attach(observer Observer, updateType string)
Detach(observer Observer, updateType string)
notify(updateType string)
}
type Observer struct {
uuid uuid.UUID
}
observer_one.go
type ObserverOne struct {
Observer
}
func (o *ObserverOne) Update(subject *SubjectInterface, updateType string) {}
主.go
subjectOne := &SubjectOne{}
observerOne := &ObserverOne{Observer{uuid: uuid.New()}}
subjectOne.Attach(observerOne, "update_type")
我希望能够使用 SubjectInterface
作为 ObserverOne
中 Update()
方法的参数,这样我就可以避免依赖在我的 subject
包和我的 observer
包之间,但出现以下编译时错误。
observers/observer_one.go:29:35: cannot use &observer (type *ObserverOne) as type subjects.ObserverInterface in argument to SubjectOne.Subject.Attach:
*ObserverOne does not implement subjects.ObserverInterface (wrong type for Update method)
have Update(*SubjectInterface, string)
want Update(*subjects.Subject, string)
如果我将 observer_one.go 中 Update()
的定义替换为以下内容,它可以正常编译,但我认为我的想法是使用接口(interface)来解耦包:
func (o *ObserverOne) Update(subject *subjects.Subject, updateType string) {}
最佳答案
首先,不要使用指向接口(interface)的指针。
func (o *ObserverOne) Update(subject *SubjectInterface, updateType string) {}
应该是
func (o *ObserverOne) Update(subject SubjectInterface, updateType string) {}
其次,您已将接口(interface)定义为需要具体类型:
type ObserverInterface interface {
Update(subject *Subject, updateType string)
}
相反,让它接受一个接口(interface):
type ObserverInterface interface {
Update(subject SubjectInterface, updateType string)
}
关于go - Go方式实现观察者设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57027133/