常用設(shè)計模式
1. 單例模式:
package singleton
import (
"sync"
)
type singleton struct {
}
var ins *singleton
var once sync.Once
func GetInsOr() *singleton {
once.Do(func() {
ins = &singleton{}
})
return ins
}
2. 簡單工廠模式
type Person struct {
Name string
Age int
}
func (p Person) Greet() {
fmt.Printf("Hi! My name is %s", p.Name)
}
func NewPerson(name string, age int) *Person {
return &Person{
Name: name,
Age: age,
}
}
3. 抽象工廠模式
它返回的是接口而不是結(jié)構(gòu)體砚嘴。
type Person interface {
Greet()
}
type person struct {
name string
age int
}
func (p person) Greet() {
fmt.Printf("Hi! My name is %s", p.name)
}
// Here, NewPerson returns an interface, and not the person struct itself
func NewPerson(name string, age int) Person {
return person{
name: name,
age: age,
}
}
4. 工廠方法模式
type Person struct {
name string
age int
}
func NewPersonFactory(age int) func(name string) Person {
return func(name string) Person {
return Person{
name: name,
age: age,
}
}
}
5. 策略模式
在項目開發(fā)中穿稳,我們經(jīng)常要根據(jù)不同的場景呼股,采取不同的措施阳啥,也就是不同的策略沸移。比如床牧,假設(shè)我們需要對 a荣回、b 這兩個整數(shù)進行計算,根據(jù)條件的不同戈咳,需要執(zhí)行不同的計算方式心软。為了解耦,需要使用策略模式著蛙,定義一些獨立的類來封裝不同的算法删铃,每一個類封裝一個具體的算法(即策略)。
package strategy
// 策略模式
// 定義一個策略類
type IStrategy interface {
do(int, int) int
}
// 策略實現(xiàn):加
type add struct{}
func (*add) do(a, b int) int {
return a + b
}
// 策略實現(xiàn):減
type reduce struct{}
func (*reduce) do(a, b int) int {
return a - b
}
// 具體策略的執(zhí)行者
type Operator struct {
strategy IStrategy
}
// 設(shè)置策略
func (operator *Operator) setStrategy(strategy IStrategy) {
operator.strategy = strategy
}
// 調(diào)用策略中的方法
func (operator *Operator) calculate(a, b int) int {
return operator.strategy.do(a, b)
}
6. 模板模式
模板模式就是將一個類中能夠公共使用的方法放置在抽象類中實現(xiàn)踏堡,將不能公共使用的方法作為抽象方法猎唁,強制子類去實現(xiàn),這樣就做到了將一個類作為一個模板顷蟆,讓開發(fā)者去填充需要填充的地方诫隅。
package template
import "fmt"
type Cooker interface {
fire()
cooke()
outfire()
}
// 類似于一個抽象類
type CookMenu struct {
}
func (CookMenu) fire() {
fmt.Println("開火")
}
// 做菜,交給具體的子類實現(xiàn)
func (CookMenu) cooke() {
}
func (CookMenu) outfire() {
fmt.Println("關(guān)火")
}
// 封裝具體步驟
func doCook(cook Cooker) {
cook.fire()
cook.cooke()
cook.outfire()
}
type XiHongShi struct {
CookMenu
}
func (*XiHongShi) cooke() {
fmt.Println("做西紅柿")
}
type ChaoJiDan struct {
CookMenu
}
func (ChaoJiDan) cooke() {
fmt.Println("做炒雞蛋")
}
7. 代理模式
可以為另一個對象提供一個替身或者占位符帐偎,以控制對這個對象的訪問逐纬。
package proxy
import "fmt"
type Seller interface {
sell(name string)
}
// 火車站
type Station struct {
stock int //庫存
}
func (station *Station) sell(name string) {
if station.stock > 0 {
station.stock--
fmt.Printf("代理點中:%s買了一張票,剩余:%d \n", name, station.stock)
} else {
fmt.Println("票已售空")
}
}
// 火車代理點
type StationProxy struct {
station *Station // 持有一個火車站對象
}
func (proxy *StationProxy) sell(name string) {
if proxy.station.stock > 0 {
proxy.station.stock--
fmt.Printf("代理點中:%s買了一張票,剩余:%d \n", name, proxy.station.stock)
} else {
fmt.Println("票已售空")
}
}
8. 選項模式
package options
import (
"time"
)
type Connection struct {
addr string
cache bool
timeout time.Duration
}
const (
defaultTimeout = 10
defaultCaching = false
)
type options struct {
timeout time.Duration
caching bool
}
// Option overrides behavior of Connect.
type Option interface {
apply(*options)
}
type optionFunc func(*options)
func (f optionFunc) apply(o *options) {
f(o)
}
func WithTimeout(t time.Duration) Option {
return optionFunc(func(o *options) {
o.timeout = t
})
}
func WithCaching(cache bool) Option {
return optionFunc(func(o *options) {
o.caching = cache
})
}
// Connect creates a connection.
func NewConnect(addr string, opts ...Option) (*Connection, error) {
options := options{
timeout: defaultTimeout,
caching: defaultCaching,
}
for _, o := range opts {
o.apply(&options)
}
return &Connection{
addr: addr,
cache: options.caching,
timeout: options.timeout,
}, nil
}
選項模式通常適用于以下場景:
- 結(jié)構(gòu)體參數(shù)很多,創(chuàng)建結(jié)構(gòu)體時削樊,我們期望創(chuàng)建一個攜帶默認值的結(jié)構(gòu)體變量豁生,并選擇性修改其中一些參數(shù)的值。
- 結(jié)構(gòu)體參數(shù)經(jīng)常變動漫贞,變動時我們又不想修改創(chuàng)建實例的函數(shù)甸箱。例如:結(jié)構(gòu)體新增一個 retry 參數(shù),但是又不想在 NewConnect 入?yún)⒘斜碇刑砑觬etry int這樣的參數(shù)聲明迅脐。
參考文章
- Go 語言項目開發(fā)實戰(zhàn)/設(shè)計模式