Go实战--Design Patterns in Golang 之单利模式(Singleton)

Go实战--Design Patterns in Golang 之单利模式(Singleton),第1张

概述小插曲: 一猎头拉了个几百人的微信群,主要是沈阳、大连从事IT工作的人,以下是某几个时段的聊天截图: 回不去的东北……很多同事都说如果我选择回东北,肯定后悔,用不了多久还会回北京。 生命不止,继续 go go go !!! golang的基础知识介绍了很多很多了,主要是一些官方package的介绍。 golang的实战也介绍了很多很多了,包括了很多web框架,rest api, *** 作各种类型的数据库

小插曲:

一猎头拉了个几百人的微信群,主要是沈阳、大连从事IT工作的人,以下是某几个时段的聊天截图:




回不去的东北……很多同事都说如果我选择回东北,肯定后悔,用不了多久还会回北京。

生命不止,继续 go go go !!!

golang的基础知识介绍了很多很多了,主要是一些官方package的介绍。
golang的实战也介绍了很多很多了,包括了很多web框架,rest API, *** 作各种类型的数据库,各种认证方式,等等等。

接下来,就要跟大家一起学习,分享golang中的设计模式了。

PS: 设计模式的重要性不用多说,也是面试官常常问到的问题。但是对于设计模式,更多的是仁者见仁智者见智。要在实际工作中,代码的积累,工程的积累,再进行深度的思考,逐渐形成的一种思维。

Patterns,顾名思义,具有某种重复性规律的方案。Design Patterns,就是设计过程中可以反复使用的、可以解决特定问题的设计方法。

当然,是从最普遍,最简单的单利模式入手了。

何为单例

wiki:
In software engineering,the singleton pattern is a software design pattern that restricts the instantiation of a class to one object.

举个栗子:
windows 是多进程多线程的,在 *** 作一个文件的时候,就不可避免地出现多个进程或线程同时 *** 作一个文件的现象,所以所有文件的处理必须通过唯一的实例来进行。这就可以使用单例模式来解决该问题。

C++中实现单例:

class S{    public:        static S& getInstance()        {            static S    instance; // Guaranteed to be destroyed.                                  // Instantiated on first use.            return instance;        }    private:        S() {}                    // Constructor? (the {} brackets) are needed here.        // C++ 03        // ========        // Don't forget to declare these two. You want to make sure they        // are unacceptable otherwise you may accIDentally get copIEs of        // your singleton appearing.        S(S const&);              // Don't Implement        voID operator=(S const&); // Don't implement        // C++ 11        // =======        // We can use the better technique of deleting the methods        // we don't want.    public:        S(S const&)               = delete;        voID operator=(S const&)  = delete;        // Note: Scott Meyers mentions in his Effective Modern        // C++ book,that deleted functions should generally        // be public as it results in better error messages        // due to the compilers behavior to check accessibility        // before deleted status};

把构造函数作为私有。

c++实现单例完整栗子:

#include <windows.h>#include <iostream>using namespace std;class SingletonClass {public:    static SingletonClass* getInstance() {    return (!m_instanceSingleton) ?        m_instanceSingleton = new SingletonClass :         m_instanceSingleton;    }private:    // private constructor and destructor    SingletonClass() { cout << "SingletonClass instance created!\n"; }    ~SingletonClass() {}    // private copy constructor and assignment operator    SingletonClass(const SingletonClass&);    SingletonClass& operator=(const SingletonClass&);    static SingletonClass *m_instanceSingleton;};SingletonClass* SingletonClass::m_instanceSingleton = nullptr;int main(int argc,const char * argv[]) {    SingletonClass *singleton;    singleton = singleton->getInstance();    cout << singleton << endl;    // Another object gets the reference of the first object!    SingletonClass *anotherSingleton;    anotherSingleton = anotherSingleton->getInstance();    cout << anotherSingleton << endl;    Sleep(5000);    return 0;}
golang中的单例

但是,在golang的世界中,没有private public static等关键字,也没有面向对象中类的概念。

那么golang是如何控制访问范围的呢?
首字母大写,代表对外部可见,首字母小写代表对外部不可见,适用于所有对象,包括函数、方法

golang中全局变量
可以使用全局变量,达到c++中static的效果

golang标准库中的单例模式使用示例
golang是开源的,当我们不知道怎么写代码的时候,完全可以读一读golang的源码。
对于单例模式,例如net/Http包中的 http.DefaultClIEnt 和 http.DefaultServeMux。

http.DefaultClIEnt
type ClIEnt struct {    Transport roundtripper    CheckRedirect func(req *Request,via []*Request) error    Jar cookieJar    Timeout time.Duration  }var DefaultClIEnt = &ClIEnt{}
http.DefaultServeMux
// DefaultServeMux is the default ServeMux used by Serve.  var DefaultServeMux = &defaultServeMux

golang中单例实现(不完美)
先看代码:

package singletontype single struct {        O interface{};}var instantiated *single = nilfunc New() *single {        if instantiated == nil {                instantiated = new(single);        }        return instantiated;}

看似不错,但是不是线程安全的。

golang中线程安全的单例模式

使用了sync包:
func (*Once) Do

func (o *Once) Do(f func())

Do calls the function f if and only if Do is being called for the first time for this instance of Once

package singletonimport "sync"type single struct {        O interface{};}var instantiated *singlevar once sync.Oncefunc New() *single {        once.Do(func() {                instantiated = &single{}        })        return instantiated}

单例模式 *** 作数据库

package dbimport "fmt"type repository struct {    items map[string]string    mu    sync.RWMutex}func (r *repository) Set(key,data string) {    r.mu.Lock()    defer r.mu.Unlock()    r.items[key] = data}func (r *repository) Get(key string) (string,error) {    r.mu.RLock()    defer r.mu.RUnlock()    item,ok := r.items[key]    if !ok {        return "",fmt.Errorf("The '%s' is not presented",key)    }    return item,nil}var (    r    *repository    once sync.Once)func Repository() *repository {    once.Do(func() {        r = &repository{            items: make(map[string]string),}    })    return r}

参考:
http://blog.ralch.com/tutorial/design-patterns/golang-singleton/

总结

以上是内存溢出为你收集整理的Go实战--Design Patterns in Golang 之单利模式(Singleton)全部内容,希望文章能够帮你解决Go实战--Design Patterns in Golang 之单利模式(Singleton)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1271748.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-08
下一篇 2022-06-08

发表评论

登录后才能评论

评论列表(0条)

保存