好记性不如烂笔头,学习编程的最好方式就是自己把代码动手敲一遍
1.策略模式(strategy)在实际应用中, 我们对不同的场景要采取不同的应对措施,也就是不同的策略。定义一个接口,传入的不同对象实现了接口,因此自动调用对应的策略
其中strategy.go:
package strategy
import "fmt"
type Payment struct {
payctx *PayCtx
strategy Strategy
}
type Strategy interface {
Pay(*PayCtx)
}
type PayCtx struct {
money int
name string
}
func NewPayment(money int, name string, strategy Strategy) *Payment {
return &Payment{
payctx: &PayCtx{
money: money,
name: name,
},
strategy: strategy,
}
}
func (p *Payment) Pay() {
p.strategy.Pay(p.payctx)
}
type Cash struct{}
func (cash *Cash) Pay(ctx *PayCtx) {
fmt.Printf("%s使用现金支付了%d\n", ctx.name, ctx.money)
}
type Bank struct{}
func (bank *Bank) Pay(ctx *PayCtx) {
fmt.Printf("%s使用银行支付了%d\n", ctx.name, ctx.money)
}
测试代码strategy_test.go:
package strategy
import "testing"
func TestNewPayment(t *testing.T) {
a := NewPayment(18, "zr", &Cash{})
b := NewPayment(9090, "sys", &Bank{})
a.Pay()
b.Pay()
}
单例模式(singleton)
许多时候软件内只需要一个实例对象,此时便可用单例模式创建此对象;
单例模式算是go中实现最简单的了:
package singleton
import "sync"
var s *Singleton
var once sync.Once
type Singleton struct{}
func GetSingleton() *Singleton {
once.Do(func() {
s = &Singleton{}
})
return s
}
测试singleton_test.go
package singleton
import (
"sync"
"testing"
)
func TestGetSingleton(t *testing.T) {
var wg sync.WaitGroup
wg.Add(1000)
start := make(chan struct{})
arr := make([]*Singleton, 1000)
for i := 0; i < 1000; i++ {
//同时起1000个goroutine
go func(index int) {
<-start // 全部阻塞在此
singleton := GetSingleton() // 获取单例对象
arr[index] = singleton
wg.Done() // 将每个goroutine获得的单例对象存储到数组
}(i)
}
close(start) // 关闭通道的同时,1000个goroutine同时执行
wg.Wait() // 阻塞等待所有goroutine执行完成
for i := 0; i < 999; i++ {
if arr[i] != arr[i+1] {
t.Fatalf("同时有多个实例")
}
}
}
简单工厂模式(simple_factory)
当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知道其创建细节。
package simple_factory
type Production interface {
create() string
}
type Factory struct{}
func (f *Factory) NewProduction(name int) Production {
switch name {
case 1:
return &Product1{}
case 2:
return &Product2{}
default:
return nil
}
}
type Product1 struct{}
func (p Product1) create() string {
return "产品1"
}
type Product2 struct{}
func (p Product2) create() string {
return "产品2"
}
测试代码simeple_factory_test.go
package simple_factory
import (
"testing"
)
func TestFactory_NewProduction(t *testing.T) {
factory := Factory{}
production1 := factory.NewProduction(1)
production2 := factory.NewProduction(2)
if production1.create() != "产品1" {
t.Fatalf("产品1测试失败")
}
if production2.create() != "产品2" {
t.Fatalf("产品2测试失败")
}
}
观察者模式
观察者模式用于触发联动。
subject的改变会触发他所有观察者的相关动作
package observer
import "fmt"
type IObserver interface {
Notify()
}
type ISubject interface {
AddObserver(observer ...IObserver)
NotifyObserver()
}
type Observer struct{}
type Subject struct {
OArr []IObserver
}
func NewObserver() *Observer {
return &Observer{}
}
func NewSubject() *Subject {
return &Subject{}
}
func (o *Observer) Notify() {
fmt.Println("执行命令")
}
func (s *Subject) AddObserver(observer ...IObserver) {
s.OArr = append(s.OArr, observer...)
}
func (s *Subject) NotifyObserver() {
for _, v := range s.OArr {
v.Notify()
}
}
测试代码observer_test.go:
package observer
import "testing"
func TestObserver_Notify(t *testing.T) {
observer := NewObserver()
subject := NewSubject()
subject.AddObserver(observer)
subject.NotifyObserver()
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)