Go语言设计模式:创建型模式
Go语言设计模式创建型模式一、设计模式概述设计模式是软件设计中反复出现问题的解决方案。Go语言作为一种现代化的编程语言同样可以应用经典的设计模式。Go语言中的设计模式特点接口优先通过接口实现解耦组合优于继承Go不支持继承使用组合实现代码复用并发安全考虑并发场景下的设计简洁性避免过度设计二、单例模式单例模式确保一个类只有一个实例并提供全局访问点。饿汉式单例package singleton import sync type Singleton struct { data string } var instance *Singleton var once sync.Once func GetInstance() *Singleton { once.Do(func() { instance Singleton{ data: initialized, } }) return instance } func (s *Singleton) SetData(data string) { s.data data } func (s *Singleton) GetData() string { return s.data }懒汉式单例带缓存package singleton import ( sync time ) type Config struct { timeout time.Duration retries int } var ( configInstance *Config configMu sync.RWMutex ) func GetConfig() *Config { // 先检查快速路径 configMu.RLock() if configInstance ! nil { defer configMu.RUnlock() return configInstance } configMu.RUnlock() // 需要初始化获取写锁 configMu.Lock() defer configMu.Unlock() // 双重检查 if configInstance nil { configInstance Config{ timeout: 30 * time.Second, retries: 3, } } return configInstance }三、工厂模式工厂模式封装对象的创建过程使客户端代码与具体实现解耦。简单工厂package factory type Product interface { GetName() string } type ConcreteProductA struct{} func (p *ConcreteProductA) GetName() string { return Product A } type ConcreteProductB struct{} func (p *ConcreteProductB) GetName() string { return Product B } func NewProduct(productType string) Product { switch productType { case A: return ConcreteProductA{} case B: return ConcreteProductB{} default: return nil } }工厂方法package factory type Factory interface { CreateProduct() Product } type ConcreteFactoryA struct{} func (f *ConcreteFactoryA) CreateProduct() Product { return ConcreteProductA{} } type ConcreteFactoryB struct{} func (f *ConcreteFactoryB) CreateProduct() Product { return ConcreteProductB{} } func main() { var factory Factory ConcreteFactoryA{} product : factory.CreateProduct() println(product.GetName()) }抽象工厂package factory type Button interface { Click() string } type Checkbox interface { Check() string } type GUIFactory interface { CreateButton() Button CreateCheckbox() Checkbox } type WindowsButton struct{} func (b *WindowsButton) Click() string { return Windows button clicked } type WindowsCheckbox struct{} func (c *WindowsCheckbox) Check() string { return Windows checkbox checked } type WindowsFactory struct{} func (f *WindowsFactory) CreateButton() Button { return WindowsButton{} } func (f *WindowsFactory) CreateCheckbox() Checkbox { return WindowsCheckbox{} }四、建造者模式建造者模式将复杂对象的构建过程与其表示分离使同样的构建过程可以创建不同的表示。package builder type Product struct { PartA string PartB string PartC string } type Builder interface { BuildPartA() BuildPartB() BuildPartC() GetProduct() *Product } type ConcreteBuilder struct { product *Product } func NewConcreteBuilder() *ConcreteBuilder { return ConcreteBuilder{ product: Product{}, } } func (b *ConcreteBuilder) BuildPartA() { b.product.PartA Part A } func (b *ConcreteBuilder) BuildPartB() { b.product.PartB Part B } func (b *ConcreteBuilder) BuildPartC() { b.product.PartC Part C } func (b *ConcreteBuilder) GetProduct() *Product { return b.product } type Director struct { builder Builder } func (d *Director) Construct() *Product { d.builder.BuildPartA() d.builder.BuildPartB() d.builder.BuildPartC() return d.builder.GetProduct() }五、原型模式原型模式通过复制现有对象来创建新对象避免重复的初始化过程。package prototype import encoding/json type Prototype interface { Clone() Prototype } type ConcretePrototype struct { ID int Name string Items []string } func (p *ConcretePrototype) Clone() Prototype { // 深拷贝 data, _ : json.Marshal(p) clone : ConcretePrototype{} json.Unmarshal(data, clone) return clone } func (p *ConcretePrototype) CloneShallow() Prototype { // 浅拷贝 clone : *p return clone }六、抽象工厂模式实战场景数据库连接工厂package factory import database/sql type Database interface { Connect() error Query(sql string) (*sql.Rows, error) Close() error } type DatabaseFactory interface { CreateDatabase(config map[string]string) Database } type MySQLDatabase struct { conn *sql.DB } func (m *MySQLDatabase) Connect() error { // MySQL连接逻辑 return nil } func (m *MySQLDatabase) Query(sql string) (*sql.Rows, error) { // 查询逻辑 return nil, nil } func (m *MySQLDatabase) Close() error { return m.conn.Close() } type MySQLFactory struct{} func (f *MySQLFactory) CreateDatabase(config map[string]string) Database { return MySQLDatabase{} } func NewDatabaseFactory(dbType string) DatabaseFactory { switch dbType { case mysql: return MySQLFactory{} case postgres: return PostgresFactory{} default: return nil } }七、单例模式实战场景日志管理器package logger import ( sync io os ) type Logger struct { writer io.Writer } var ( loggerInstance *Logger loggerOnce sync.Once ) func GetLogger() *Logger { loggerOnce.Do(func() { file, err : os.OpenFile(app.log, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) if err ! nil { file os.Stdout } loggerInstance Logger{ writer: file, } }) return loggerInstance } func (l *Logger) Log(message string) { l.writer.Write([]byte(message \n)) }八、建造者模式实战场景HTTP客户端配置package client import ( net/http time ) type HTTPClient struct { client *http.Client baseURL string timeout time.Duration headers map[string]string } type HTTPClientBuilder struct { baseURL string timeout time.Duration headers map[string]string } func NewHTTPClientBuilder() *HTTPClientBuilder { return HTTPClientBuilder{ timeout: 30 * time.Second, headers: make(map[string]string), } } func (b *HTTPClientBuilder) WithBaseURL(url string) *HTTPClientBuilder { b.baseURL url return b } func (b *HTTPClientBuilder) WithTimeout(timeout time.Duration) *HTTPClientBuilder { b.timeout timeout return b } func (b *HTTPClientBuilder) WithHeader(key, value string) *HTTPClientBuilder { b.headers[key] value return b } func (b *HTTPClientBuilder) Build() *HTTPClient { client : http.Client{ Timeout: b.timeout, } return HTTPClient{ client: client, baseURL: b.baseURL, timeout: b.timeout, headers: b.headers, } }九、总结创建型设计模式帮助我们管理对象的创建过程单例模式确保全局唯一实例工厂模式封装对象创建逻辑抽象工厂模式创建一系列相关对象建造者模式分步构建复杂对象原型模式通过复制创建对象在Go语言中应用这些模式时要注意利用接口实现解耦考虑并发安全性避免过度设计保持代码简洁选择合适的设计模式可以提高代码的可维护性和可扩展性。