优化扇出观察者示例的逻辑

This commit is contained in:
fantasticbin 2024-11-16 14:10:32 +08:00
parent a61d49c8c3
commit 310206ad68
2 changed files with 12 additions and 12 deletions

View File

@ -17,16 +17,16 @@ func NewSubject() Subject {
} }
// Attach 观察者绑定 // Attach 观察者绑定
func (s *Subject) Attach(observer ...Observer) { func (s *Subject) Attach(obs ...Observer) {
s.observers = append(s.observers, observer...) s.observers = append(s.observers, obs...)
} }
// Detach 观察者解绑 // Detach 观察者解绑
func (s *Subject) Detach(observer Observer) { func (s *Subject) Detach(obs Observer) {
for i, obs := range s.observers { for i, o := range s.observers {
if obs == observer { if o == obs {
s.observers = append(s.observers[:i], s.observers[i+1:]...) s.observers = append(s.observers[:i], s.observers[i+1:]...)
close(observer) close(obs)
break break
} }
} }
@ -34,18 +34,17 @@ func (s *Subject) Detach(observer Observer) {
// Notify 通知观察者 // Notify 通知观察者
func (s *Subject) Notify(data any) { func (s *Subject) Notify(data any) {
// 这里可考虑不需要使用协程运行
go s.fanOut(s.in, s.observers) go s.fanOut(s.in, s.observers)
s.in <- data s.in <- data
} }
// fanOut 扇出模式实现 // fanOut 扇出模式实现
func (s *Subject) fanOut(ch <-chan interface{}, out []Observer) { func (s *Subject) fanOut(ch <-chan interface{}, out []Observer) {
var cases []reflect.SelectCase // 绑定输入 chan 的 reflect.SelectCase
// 添加输入 chan 的 reflect.SelectCase cases := []reflect.SelectCase{
cases = append(cases, reflect.SelectCase{ {Dir: reflect.SelectRecv, Chan: reflect.ValueOf(ch)},
Dir: reflect.SelectRecv, }
Chan: reflect.ValueOf(ch),
})
go func() { go func() {
defer func() { defer func() {

View File

@ -29,5 +29,6 @@ func TestObserver(t *testing.T) {
newUser2 := "gan" newUser2 := "gan"
userRegister.Notify(newUser1) userRegister.Notify(newUser1)
userRegister.Notify(newUser2) userRegister.Notify(newUser2)
// 休眠防止主协程退出
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)
} }