一、Golang單例模式實現
單例模式是一種常見的設計模式,它保證在整個程序中只會有一個實例對象被創建和使用。在某些情況下,只需要一個對象,例如在配置信息中心。在Golang中,實現單例模式需要考慮Golang的並發特性。
下面是一個常見的經典實現,使用懶惰初始化的方法來確保只會實例化一次實例對象。
type Singleton struct {
}
var instance *Singleton
func GetInstance() *Singleton {
once.Do(func() {
instance = &Singleton{}
})
return instance
}
var once sync.Once
在這個實現中,Golang標準庫提供了一個sync.Once類型來確保初始化動作只執行一次。在GetInstance()方法中,我們首先判斷實例對象是否已經被創建,如果沒有,那麼就使用once.Do()方法創建一個實例。
二、Golang工廠模式
Golang工廠模式是一種創建型的設計模式,它定義了一個對象創建的介面,但是讓子類決定實例化哪個類。這種方式可以避免暴露對象創建的具體實現邏輯。
下面是一個簡單的Golang工廠模式實現,它使用GetAnimal()方法來根據輸入的動物名創建對應的動物對象。
type Animal interface {
Speak() string
}
type Dog struct{}
func (d Dog) Speak() string {
return "Woof!"
}
type Cat struct{}
func (c Cat) Speak() string {
return "Meow!"
}
func GetAnimal(animalType string) Animal {
switch animalType {
case "dog":
return Dog{}
case "cat":
return Cat{}
default:
return nil
}
}
在這個實現中,我們定義了一個Animal介面和兩個實現類:Dog和Cat。GetAnimal()方法根據輸入的字元串來返回對應的動物對象。
三、Go單例模式
Go單例模式是一種用於解決資源競爭問題的實現方式。如果多個協程同時訪問某個變數,會出現資源訪問衝突的問題。Go單例模式通過使用channel來限制只有一個協程在任何時刻訪問共享資源。
下面是一個簡單的Go單例模式實現,其中使用了無緩衝的channel來同步協程之間的訪問。
type Singleton struct{}
var once sync.Once
var instance *Singleton
var ch = make(chan int, 1)
func GetInstance() *Singleton {
if instance == nil {
ch <- 1
defer func() { <-ch }()
once.Do(func() {
instance = &Singleton{}
})
}
return instance
}
在這個實現中,我們定義了一個無緩衝的channel來控制多個協程之間的訪問。在GetInstance()方法中,我們首先將ch的一個元素壓入隊列中,然後在函數退出時將其出隊。這樣,可以確保在任何時刻只有一個協程能夠訪問代碼塊中的內容。
四、Golang設計模式
設計模式是一種解決軟體工程中常見問題的經驗總結,它幫助開發者對程序進行架構和設計,提高軟體的可維護性、可擴展性和可重用性。Golang支持大多數常見的設計模式。
下面是一些常見的Golang設計模式:
1. 觀察者模式
觀察者模式定義了對象之間的一種依賴關係,當被觀察對象狀態發生變化時,所有依賴於它的觀察者都將得到通知。在Golang中,可以使用channel來實現觀察者模式。
type Observer interface {
Update(int)
}
type Subject struct {
observers []Observer
}
func (s *Subject) Attach(o Observer) {
s.observers = append(s.observers, o)
}
func (s *Subject) Notify(val int) {
for _, observer := range s.observers {
observer.Update(val)
}
}
type ConcreteObserver struct{}
func (c *ConcreteObserver) Update(val int) {
fmt.Printf("Received update with value %v\n", val)
}
func runObserverPattern() {
subj := &Subject{observers: []Observer{&ConcreteObserver{}}}
subj.Notify(10)
}
2. 策略模式
策略模式定義了一系列演算法,將每個演算法封裝為一個單獨的類,並讓它們可以互換。這種設計模式可以使演算法獨立於使用它的客戶端而變化。
type Strategy interface {
Execute()
}
type ConcreteStrategy1 struct{}
func (s1 *ConcreteStrategy1) Execute() {
fmt.Println("Executing Concrete Strategy 1...")
}
type ConcreteStrategy2 struct{}
func (s2 *ConcreteStrategy2) Execute() {
fmt.Println("Executing Concrete Strategy 2...")
}
type Context struct {
strategy Strategy
}
func (c *Context) SetStrategy(strategy Strategy) {
c.strategy = strategy
}
func (c *Context) Execute() {
c.strategy.Execute()
}
func runStrategyPattern() {
c := &Context{}
c.SetStrategy(&ConcreteStrategy1{})
c.Execute()
c.SetStrategy(&ConcreteStrategy2{})
c.Execute()
}
3. 訪問者模式
訪問者模式是一種行為型模式,它將某些演算法封裝到類中。在Golang中,訪問者模式通常使用函數代替類來實現。
type Element interface {
Accept(Visitor)
}
type ConcreteElement1 struct{}
func (e1 *ConcreteElement1) Accept(v Visitor) {
v.VisitConcreteElement1(e1)
}
type ConcreteElement2 struct{}
func (e2 *ConcreteElement2) Accept(v Visitor) {
v.VisitConcreteElement2(e2)
}
type Visitor interface {
VisitConcreteElement1(*ConcreteElement1)
VisitConcreteElement2(*ConcreteElement2)
}
type ConcreteVisitor struct{}
func (c *ConcreteVisitor) VisitConcreteElement1(e1 *ConcreteElement1) {
fmt.Println("Visiting Concrete Element 1 by Concrete Visitor...")
}
func (c *ConcreteVisitor) VisitConcreteElement2(e2 *ConcreteElement2) {
fmt.Println("Visiting Concrete Element 2 by Concrete Visitor...")
}
func runVisitorPattern() {
elements := []Element{&ConcreteElement1{}, &ConcreteElement2{}}
v := &ConcreteVisitor{}
for _, el := range elements {
el.Accept(v)
}
}
4. ACM模式
ACM(Active Class Middleware)模式是一種以類為中心的分散式體系結構模式。在ACM模式中,運行時環境中有許多對象扮演不同的角色,這些對象在運行過程中相互作用,以實現分散式系統的功能。
在Golang中,可以通過使用GRPC實現ACM模式。
下面是一個簡單的GRPC示例:
// server
type GreeterServer struct{}
func (s *GreeterServer) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil
}
func main() {
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", 50051))
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterGreeterServer(s, &GreeterServer{})
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
// client
func main() {
conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
c := pb.NewGreeterClient(conn)
r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: "World"})
if err != nil {
log.Fatalf("could not greet: %v", err)
}
log.Printf("Greeting: %s", r.GetMessage())
}
五、總結
Golang單例模式是一種常見的設計模式,它保證在整個程序中只會有一個實例對象被創建和使用。在Golang中,實現單例模式需要考慮Golang的並發特性。此外,Golang還支持許多其他常見的設計模式,例如工廠模式、觀察者模式、策略模式、訪問者模式和ACM模式。
原創文章,作者:ZKOL,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/138137.html
微信掃一掃
支付寶掃一掃