Observer Design Pattern in Go (Golang)
文章推薦指數: 80 %
Observer Design Pattern is a behavioral design pattern. This pattern allows an instance (called subject) to publish events to other multiple ... Note:InterestedinunderstandinghowallotherdesignpatternscanbeimplementedinGO.Pleaseseethisfullreference–AllDesignPatternsinGo(Golang) TableofContents Introduction:UMLDiagram:Mapping:PracticalExample:FullWorkingCode: Introduction: ObserverDesignPatternisabehavioraldesignpattern.Thispatternallowsaninstance(calledsubject)topublisheventstoothermultipleinstances(calledobservers). Theseobserverssubscribetothesubjectandhencegetnotifiedbyeventsincaseofanychangehappeninginthesubject. Let’stakeanexample.IntheE-Commercewebsite,manyitemsgooutofstock.Therecanbecustomers,whoareinterestedinaparticularitemthatwentoutofstock.Therearethreesolutionstothisproblem Thecustomerkeepscheckingtheavailabilityoftheitematsomefrequency.E-CommercebombardcustomerswithallnewitemsavailablewhichareinstockThecustomersubscribesonlytotheparticularitemheisinterestedin andgetsnotifiedinthecasethatitemisavailable.Also,multiplecustomerscansubscribetothesameproduct Option3ismostviable,andthisiswhatObserverPatterisallabout.Themajorcomponentsoftheobserverpatternare: Subject–Itistheinstancetowhichpublishesaneventwhenanythingchanges. Observer–Itsubscribestothesubjectandgetsnotifiedbytheevents. Generally,SubjectandObserverareimplementedasaninterface.Concreteimplementationofbothareused UMLDiagram: Mapping: ThebelowtablerepresentsthemappingfromtheUMLdiagramactorstoactualimplementationactorsin“PracticalExample”below Subjectsubject.goConcreteSubjectitem.goobserverobserver.goConcreteObserver1customer.goClientmain.go PracticalExample: subject.go packagemain typesubjectinterface{ register(Observerobserver) deregister(Observerobserver) notifyAll() } item.go packagemain import"fmt" typeitemstruct{ observerList[]observer namestring inStockbool } funcnewItem(namestring)*item{ return&item{ name:name, } } func(i*item)updateAvailability(){ fmt.Printf("Item%sisnowinstock\n",i.name) i.inStock=true i.notifyAll() } func(i*item)register(oobserver){ i.observerList=append(i.observerList,o) } func(i*item)deregister(oobserver){ i.observerList=removeFromslice(i.observerList,o) } func(i*item)notifyAll(){ for_,observer:=rangei.observerList{ observer.update(i.name) } } funcremoveFromslice(observerList[]observer,observerToRemoveobserver)[]observer{ observerListLength:=len(observerList) fori,observer:=rangeobserverList{ ifobserverToRemove.getID()==observer.getID(){ observerList[observerListLength-1],observerList[i]=observerList[i],observerList[observerListLength-1] returnobserverList[:observerListLength-1] } } returnobserverList } observer.go packagemain typeobserverinterface{ update(string) getID()string } customer.go packagemain import"fmt" typecustomerstruct{ idstring } func(c*customer)update(itemNamestring){ fmt.Printf("Sendingemailtocustomer%sforitem%s\n",c.id,itemName) } func(c*customer)getID()string{ returnc.id } main.go packagemain funcmain(){ shirtItem:=newItem("NikeShirt") observerFirst:=&customer{id:"[email protected]"} observerSecond:=&customer{id:"[email protected]"} shirtItem.register(observerFirst) shirtItem.register(observerSecond) shirtItem.updateAvailability() } Output: ItemNikeShirtisnowinstock Sendingemailtocustomer[email protected]foritemNikeShirt Sendingemailtocustomer[email protected]foritemNikeShirt FullWorkingCode: packagemain import"fmt" typesubjectinterface{ register(Observerobserver) deregister(Observerobserver) notifyAll() } typeitemstruct{ observerList[]observer namestring inStockbool } funcnewItem(namestring)*item{ return&item{ name:name, } } func(i*item)updateAvailability(){ fmt.Printf("Item%sisnowinstock\n",i.name) i.inStock=true i.notifyAll() } func(i*item)register(oobserver){ i.observerList=append(i.observerList,o) } func(i*item)deregister(oobserver){ i.observerList=removeFromslice(i.observerList,o) } func(i*item)notifyAll(){ for_,observer:=rangei.observerList{ observer.update(i.name) } } funcremoveFromslice(observerList[]observer,observerToRemoveobserver)[]observer{ observerListLength:=len(observerList) fori,observer:=rangeobserverList{ ifobserverToRemove.getID()==observer.getID(){ observerList[observerListLength-1],observerList[i]=observerList[i],observerList[observerListLength-1] returnobserverList[:observerListLength-1] } } returnobserverList } typeobserverinterface{ update(string) getID()string } typecustomerstruct{ idstring } func(c*customer)update(itemNamestring){ fmt.Printf("Sendingemailtocustomer%sforitem%s\n",c.id,itemName) } func(c*customer)getID()string{ returnc.id } funcmain(){ shirtItem:=newItem("NikeShirt") observerFirst:=&customer{id:"[email protected]"} observerSecond:=&customer{id:"[email protected]"} shirtItem.register(observerFirst) shirtItem.register(observerSecond) shirtItem.updateAvailability() } Output: ItemNikeShirtisnowinstock Sendingemailtocustomer[email protected]foritemNikeShirt Sendingemailtocustomer[email protected]foritemNikeShirt designgolangobserverobserverdesignpatterningopattern Follow@golangbyexample Searchfor: PopularArticles GolangComprehensiveTutorialSeries AllDesignPatternsinGo(Golang) Sliceingolang VariablesinGo(Golang)–CompleteGuide OOP:InheritanceinGOLANGcompleteguide UsingContextPackageinGO(Golang)–CompleteGuide AlldatatypesinGolangwithexamples UnderstandingtimeanddateinGo(Golang)–CompleteGuide
延伸文章資訊
- 1Go observer pattern example - gist GitHub
Go observer pattern example. GitHub Gist: instantly share code, notes, and snippets.
- 2The Observer Design Pattern In Go - Morioh
The Observer design pattern is a fundamental tool for any capable software engineer. In one sente...
- 3design-pattern-golang/observer.go at master - GitHub
package observer. import "fmt". type Subject struct {. observers []Observer. context string. } fu...
- 4Observer Design Pattern in Golang with an Example
Observer Design Pattern is a software design pattern that lets you define a subscription mechanis...
- 5Observer pattern in Go language - Stack Overflow
The Go way to implement the Observer design pattern - Stack ...