一、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/n/138137.html
微信扫一扫
支付宝扫一扫