Giter Site home page Giter Site logo

golang-design-pattern's People

Contributors

a11might avatar dhlin avatar eval-exec avatar fgksgf avatar kongtianyi avatar pomo16 avatar senghoo avatar xpzouying avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

golang-design-pattern's Issues

想要增加一些新的设计模式

作者您好,您这个repo似乎只有《研磨设计模式》中提到的设计模式,我是否能增加一些其他设计模式的go实现并提交pull request呢?还是说在自己的repo中引用您的repo?

适配器模式,不谢

`
type InterA interface {
DoA()
}

type classA struct{}

func (a classA) DoA() {
fmt.Println("do a thing")
}

func OutDoDo(a InterA) {
a.DoA()
}

// code above is original function. now you want OutDoDO do what classB do, so adapter works

type classB struct{}

func (b classB) DoB() {
fmt.Println("do b thing")
}

type adapter1 struct{}

func (ad adapter1) DoA() {
b := classB{}
b.DoB()
}

// test
func TestAdapterOutDoDo(t *testing.T) {
ad := adapter1{}
OutDoDo(ad)
}
`

发现typo

golang-design-pattern/10_observer/obserser.go
观察者模式的文件名打错了~

Provide a more realistic example

Hi,我想 pr 设计模式中部分示例,新的示例有

  • 结合现实的例子。
  • 简洁明确的命名。
  • 注释中预输出结果。
  • Readme.md 中说明示例。

举一个例子,工厂方法模式。它将存在 IGun.go \ gun.go \ ak47.go \ musket.go \ gunFactory.go \ output.txt \ factorymethod_test.go
🎉 没错,这是一个兵工厂。如果认为不错,那我将开始这个计划,当然!如果您希望维持现状,这也没关系~

单例模式中singleton结构体字段为空,多次赋值instance值是一样的

如下代码验证了空结构体多次赋值结果一样,在单例模式中golang-design-pattern/03_singleton/singleton.go line23,即使不用sync.Once 也能通过单元测试,应该给singleton添加一个字段

`package main

import (
"fmt"
)

var a1 *singleton1
var a2 *singleton2

type singleton1 struct {
}
type singleton2 struct {
d int
}

func getInstance1() *singleton1 {
a1 = &singleton1{}
return a1
}
func getInstance2() *singleton2 {
a2 = &singleton2{}
return a2
}
func main() {
b1, c1 := getInstance1(), getInstance1()
fmt.Println(b1 == c1)
//true
b2, c2 := getInstance2(), getInstance2()
fmt.Println(b2 == c2)
//false
}
`

单例模式没有unlock,并发会造成死锁

func GetInstance() *Singleton {
	if singletonInst == nil {
		// 多个线程进入这里会造成死锁
		singletonInstLock.Lock()
		if singletonInst == nil {
			singletonInst = &Singleton{}
		}
		// 应该在此处UnLock
	}
	return singletonInst
}

单例设计模式Singleton 是否应该改为包私有的,否者调用者也可以直接调用Singleton实例会对象。

package singleton

import "sync"

//Singleton 是单例模式类
type Singleton struct{}

var singleton *Singleton
var once sync.Once

//GetInstance 用于获取单例模式对象
func GetInstance() *Singleton {
	once.Do(func() {
		singleton = &Singleton{}
	})

	return singleton
}

=>

package singleton

import "sync"

//Singleton 是单例模式类
type singleton struct{}

var singleton *singleton
var once sync.Once

//GetInstance 用于获取单例模式对象
func GetInstance() *singleton {
	once.Do(func() {
		singleton = &singleton{}
	})

	return singleton
}

对单例模式实现代码的建议

给出的demo代码的确能跑通,但是利用sync.Once.Do()方法实现线程安全的话,会导致整个go进程中只能创建这一种单例
如果我想创建多个用处不同的单例的话,会导致后面的都没法成功

想了两种优化的方案

  1. 每次都先加线程锁,再判断实例
package singleton

import (
	"sync"
)

// Singleton 是单例模式接口,导出的
// 通过该接口可以避免 GetInstance 返回一个包私有类型的指针
type Singleton interface {
	foo()
}

// singleton 是单例模式类,包私有的
type singleton struct{}

func (s singleton) foo() {}

var (
	instance  *singleton
	instance2 *singleton2
	mu        sync.Mutex
)

//GetInstance 用于获取单例模式对象
func GetInstance() Singleton {
	mu.Lock()
	defer mu.Unlock()
	if instance == nil {
		instance = &singleton{}
	}

	return instance
}

type singleton2 struct {
}

func (s2 singleton2) foo() {}
func GetInstance2() Singleton {
	mu.Lock()
	defer mu.Unlock()
	if instance2 == nil {
		instance2 = &singleton2{}
	}
	return instance2
}

  1. 每次先用sync/atomic判断,再加锁判断实例
package singleton

import (
	"sync"
	"sync/atomic"
)

// Singleton 是单例模式接口,导出的
// 通过该接口可以避免 GetInstance 返回一个包私有类型的指针
type Singleton2 interface {
	foo()
}

// singleton 是单例模式类,包私有的
type singleton21 struct{}

func (s singleton21) foo() {}

var (
	instance21       *singleton21
	instance22       *singleton22
	initInstanceCnt  uint32
	initInstanceCnt2 uint32
	mu               sync.Mutex
)

//GetInstance 用于获取单例模式对象
func GetInstance21() Singleton2 {
	if atomic.LoadUint32(&initInstanceCnt) == 1 {
		return instance21
	}

	mu.Lock()
	defer mu.Unlock()

	if initInstanceCnt == 0 {
		instance21 = &singleton21{}
		atomic.StoreUint32(&initInstanceCnt, 1)
	}
	return instance21
}

type singleton22 struct {
}

func (s2 singleton22) foo() {}
func GetInstance22() Singleton {
	if atomic.LoadUint32(&initInstanceCnt2) == 1 {
		return instance22
	}

	mu.Lock()
	defer mu.Unlock()

	if initInstanceCnt2 == 0 {
		instance22 = &singleton22{}
		atomic.StoreUint32(&initInstanceCnt2, 1)
	}
	return instance22
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.