[Go] Option選項設計模式 — — 編程方式基礎入門

[Go] Option選項設計模式 — — 編程方式基礎入門

全部代碼地址,歡迎??

  • Github:https://github.com/ziyifast/ziyifast-code_instruction/tree/main/go-demo/go-option

1 介紹

在 Go 開發中,我們經常遇到需要處理多參數配置的場景。傳統方法存在諸多痛點,例如:

問題一:參數過多且順序敏感,導致我們調用時難以閱讀,不知道每個參數背后對應的含義

// 參數過多且順序敏感
func NewServer(addr string, port int, timeout time.Duration, maxConns int, tls bool) {// ...
}// 調用時難以閱讀
srv := NewServer(":8080", 3306, 10*time.Second, 100, true)

問題二:新增改動,需要修改所有調用點

// 新增參數需修改所有調用點
func NewServer(..., enableLog bool) // 新增參數破壞現有代碼

這時就可以使用Go自帶的Option方式編程。

Go Option主要有以下優勢:

  • ? 自描述性:命名選項明確參數含義
  • ? 安全擴展:新增選項不影響現有調用
  • ? 默認值處理:自動應用合理默認配置
  • ? 參數驗證:可在選項函數中實現驗證邏輯
  • ? 順序無關:任意順序傳遞選項參數

2 基礎入門

2.1 定義類結構以及Option

// 定義配置結構體
type Config struct {Timeout time.DurationMaxConn intTLS     bool
}// 定義選項函數類型
type Option func(*Config)// 步驟3:實現構造函數
func NewConfig(opts ...Option) *Config {// 設置默認值cfg := &Config{Timeout: 10 * time.Second,MaxConn: 100,TLS:     false,}// 應用所有選項for _, opt := range opts {//因為opt本身就是func,所以這里相當于調用函數,入參為cfg structopt(cfg)}return cfg
}

2.2 定義選項函數Withxx

// 帶參數的選項
func WithTimeout(t time.Duration) Option {return func(c *Config) {c.Timeout = t}
}// 無參數的選項(開關功能)
func WithTLS() Option {return func(c *Config) {c.TLS = true}
}// 帶驗證的選項
func WithMaxConn(n int) Option {return func(c *Config) {if n > 0 {c.MaxConn = n} // 否則保持默認值}
}

2.3 使用

// 只使用默認值
defaultCfg := NewConfig()// 覆蓋部分默認值
customCfg := NewConfig(WithTimeout(30*time.Second),WithMaxConn(200),
)// 啟用特定功能
secureCfg := NewConfig(WithTLS(),WithTimeout(15*time.Second),
)

全部代碼

package mainimport ("fmt""time"
)// 定義配置結構體
type Config struct {Timeout time.DurationMaxConn intTLS     bool
}// 定義選項函數類型
type Option func(*Config)// 實現構造函數
func NewConfig(opts ...Option) *Config {// 設置默認值cfg := &Config{Timeout: 10 * time.Second,MaxConn: 100,TLS:     false,}// 應用所有選項for _, opt := range opts {opt(cfg)}return cfg
}// 帶參數的選項
func WithTimeout(t time.Duration) Option {return func(c *Config) {c.Timeout = t}
}// 無參數的選項(開關功能)
func WithTLS() Option {return func(c *Config) {c.TLS = true}
}// 帶驗證的選項
func WithMaxConn(n int) Option {return func(c *Config) {if n > 0 {c.MaxConn = n} // 否則保持默認值}
}func main() {// 啟用特定功能secureCfg := NewConfig(WithTLS(),WithTimeout(15*time.Second),)fmt.Println(secureCfg)
}

3. 實戰使用

Go Option方式可以用在數據庫配置、HTTP服務配置、客戶端連接配置、日志系統配置等。這里以HTTP服務配置為例。

package mainimport ("fmt""time"
)type Option func(*ServerConfig)type ServerConfig struct {Addr        stringReadTimeout time.DurationIdleTimeout time.DurationEnableCORS  bool
}func NewServer(addr string, opts ...Option) *ServerConfig {cfg := &ServerConfig{Addr:        addr,ReadTimeout: 5 * time.Second,IdleTimeout: 30 * time.Second,}for _, opt := range opts {opt(cfg)}return cfg
}// 組合選項:同時設置多個相關參數
func WithTimeouts(read, idle time.Duration) Option {return func(s *ServerConfig) {s.ReadTimeout = reads.IdleTimeout = idle}
}func EnableCORS() Option {return func(s *ServerConfig) {s.EnableCORS = true}
}func main() {// 使用示例server := NewServer(":8080",WithTimeouts(10*time.Second, 60*time.Second),EnableCORS(),)fmt.Println(server)
}

4. 進階(Option與鏈式調用結合)

在 Go 中我們可以結合 Option 模式和鏈式調用可以創建高度可讀、靈活的 API,實現優雅編程。這種方式尤其適用于復雜對象的配置。
核心思想:

  1. Option 模式:使用函數閉包封裝配置邏輯
  2. 鏈式調用:每個配置方法返回對象本身,支持連續調用
package mainimport "fmt"// 目標配置對象
type Server struct {host    stringport    inttimeout int // 秒tls     bool
}// Option 函數類型:接收 *Server 的閉包
type Option func(*Server)// 鏈式包裝器(關鍵結構)
type ServerBuilder struct {options []Option
}// 創建 Builder 實例
func NewBuilder() *ServerBuilder {return &ServerBuilder{}
}// 鏈式方法:添加配置選項
func (b *ServerBuilder) WithHost(host string) *ServerBuilder {b.options = append(b.options, func(s *Server) {s.host = host})return b
}func (b *ServerBuilder) WithPort(port int) *ServerBuilder {b.options = append(b.options, func(s *Server) {s.port = port})return b
}func (b *ServerBuilder) WithTimeout(timeout int) *ServerBuilder {b.options = append(b.options, func(s *Server) {s.timeout = timeout})return b
}func (b *ServerBuilder) WithTLS(tls bool) *ServerBuilder {b.options = append(b.options, func(s *Server) {s.tls = tls})return b
}func (b *ServerBuilder) Build() *Server {// 設置默認值s := &Server{host:    "localhost",port:    8080,timeout: 30,}// 應用所有配置函數for _, option := range b.options {option(s)}return s
}func main() {server := NewBuilder().WithHost("api.ziyi.com").WithPort(443).WithTimeout(60).WithTLS(true).Build()fmt.Printf("%+v\n", server)// 輸出:&{host:api.example.com port:443 timeout:60 tls:true}
}

總結

①概念:

Option 模式是 Go 語言中處理復雜配置的優雅解決方案,它通過:

  • 功能選項(Functional Options)實現靈活的配置擴展
  • 默認值機制減少調用方負擔
  • 命名參數提高代碼可讀性
  • 零成本擴展支持未來需求變化

②使用場景:

  1. 對象需要 5個以上 配置參數時
  2. 超過 3個可選 配置項時
  3. 配置可能有 合理默認值 時
  4. 需要 高頻擴展 配置的場景
  5. 開源庫/框架中需要提供 友好API 時

實踐tips:可以從簡單的配置對象開始,當可選參數超過3個或發現構造函數參數過多時,可考慮重構為Option模式。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/82436.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/82436.shtml
英文地址,請注明出處:http://en.pswp.cn/web/82436.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Unity開發】控制手機移動端的震動

🐾 個人主頁 🐾 阿松愛睡覺,橫豎醒不來 🏅你可以不屠龍,但不能不磨劍🗡 目錄 一、前言二、Unity的Handheld.Vibrate()三、調用Android原生代碼四、NiceVibrations插件五、DeviceVibration插件六、控制游戲手…

Linux 軟件安裝方式全解(適用于 CentOS/RHEL 系統)

🐧 Linux 軟件安裝方式全解(適用于 CentOS/RHEL 系統) 在 Linux 系統中,軟件安裝方式豐富多樣,常見于以下幾種方式: 安裝方式命令/工具說明軟件包管理器(推薦)yum, dnf, apt, zypp…

前端面試題-HTML篇

1. 請談談你對 Web 標準以及 W3C 的理解和認識。 我對 Web 標準 的理解是,它就像是互聯網世界的“交通規則”,由 W3C(World Wide Web Consortium,萬維網聯盟) 這樣一個國際性組織制定。這些規則規范了我們在編寫 HTML、CSS 和 JavaScript 時應該遵循的語法和行為,比如要…

ERROR: column cl.udt_name does not exist LINE 1 navicat打開金倉表報錯

描述: ERROR: column cl.udt_name does not exist LINE 1: …a.columns cl LEFT JOlN pg type ty ON ty.typname cl.udt nam. navicat連上金倉數據庫之后,想打開一張表看看,每張表都報這個錯,打不開 解決方案: 網上…

2025年- H61-Lc169--74.搜索二維矩陣(二分查找)--Java版

1.題目描述 2.思路 方法一: 定義其實坐標,右上角的元素(0,n-1)。進入while循環(注意邊界條件,行數小于m,列數要>0)從右上角開始開始向左遍歷(比當…

Jupyter MCP服務器部署實戰:AI模型與Python環境無縫集成教程

Jupyter MCP 服務器是基于模型上下文協議(Model Context Protocol, MCP)的 Jupyter 環境擴展組件,它能夠實現大型語言模型與實時編碼會話的無縫集成。該服務器通過標準化的協議接口,使 AI 模型能夠安全地訪問和操作 Jupyter 的核心…

MySQL下載安裝配置環境變量

MySQL下載安裝配置環境變量 文章目錄 MySQL下載安裝配置環境變量一、安裝MySQL1.1 下載1.2 安裝 二、查看MySQL服務是否啟動三、配置環境變量四、驗證 一、安裝MySQL 1.1 下載 官網社區版(免費版):https://dev.mysql.com/downloads/mysql/ …

WSL 安裝 Debian 12 后,Linux 如何安裝 curl , quickjs ?

在 WSL 的 Debian 12 系統中安裝 curl 非常簡單,你可以直接使用 APT 包管理器從官方倉庫安裝。以下是詳細步驟: 1. 更新軟件包索引 首先確保系統的包索引是最新的: sudo apt update2. 安裝 curl 執行以下命令安裝 curl: sudo…

Linux入門(十四)rpmyum

RPM 是RedHat PackManager的縮寫 rpm是用于互聯網下載包的打包及安裝工具 rpm查詢 查詢已安裝的rpm列表 rpm -qa查看系統是否安裝了psmisc rpm -qa | grep psmisc rpm -q psmisc查詢軟件包信息 rpm -qi psmisc查詢軟件包中的文件 rpm -ql psmisc根據文件全路徑 查詢文件所…

[git]忽略.gitignore文件

git rm --cached .gitignore 是一個 Git 命令,主要用于 從版本控制中移除已追蹤的 .gitignore 文件,但保留該文件在本地工作目錄中。以下是詳細解析: 一、命令拆解與核心作用 語法解析 git rm:Git 的刪除命令,用于從版本庫(Repository)中移除文件。--cached:關鍵參數…

Hive SQL 中 BY 系列關鍵字全解析:從排序、分發到分組的核心用法

一、排序與分發相關 BY 關鍵字 1. ORDER BY:全局統一排序 作用:對查詢結果進行全局排序,確保最終結果集完全有序(僅允許單個 Reducer 處理數據)。 語法: SELECT * FROM table_name ORDER BY column1 [A…

網絡爬蟲 - App爬蟲及代理的使用(十一)

App爬蟲及代理的使用 一、App抓包1. App爬蟲原理2. reqable的安裝與配置1. reqable安裝教程2. reqable的配置3. 模擬器的安裝與配置1. 夜神模擬器的安裝2. 夜神模擬器的配置4. 內聯調試及注意事項1. 軟件啟動順序2. 開啟抓包功能3. reqable面板功能4. 夜神模擬器設置項5. 注意事…

【25.06】FISCOBCOS使用caliper自定義測試 通過webase 單機四節點 helloworld等進行測試

前置條件 安裝一個Ubuntu20+的鏡像 基礎環境安裝 Git cURL vim jq sudo apt install -y git curl vim jq Docker和Docker-compose 這個命令會自動安裝docker sudo apt install docker-compose sudo chmod +x /usr/bin/docker-compose docker versiondocker-compose vers…

【基礎】Unity中Camera組件知識點

一、投影模式 (Projection) 1. 透視模式 (Perspective) 原理:模擬人眼,近大遠小(錐形體視錐) 核心參數: Field of View (FOV):垂直視場角 典型值:第一人稱 60-90,駕駛艙 30-45 特…

PCA(K-L變換)人臉識別(python實現)

數據集分析 ORL數據集, 總共40個人,每個人拍攝10張人臉照片 照片格式為灰度圖像,尺寸112 * 92 特點: 圖像質量高,無需灰度運算、去噪等預處理 人臉已經位于圖像正中央,但部分圖像角度傾斜(可…

【Git】View Submitted Updates——diff、show、log

在 Git 中查看更新的內容(即工作區、暫存區或提交之間的差異)是日常開發中的常見操作。以下是常用的命令和場景說明: 文章目錄 1、查看工作區與暫存區的差異2、查看提交歷史中的差異3、查看工作區與最新提交的差異4、查看兩個提交之間的差異5…

deepseek原理和項目實戰筆記2 -- deepseek核心架構

混合專家(MoE) ??混合專家(Mixture of Experts, MoE)?? 是一種機器學習模型架構,其核心思想是通過組合多個“專家”子模型(通常為小型神經網絡)來處理不同輸入,從而提高模型的容…

GPU層次結構(Nvidia和Apple M芯片,從硬件到pytorch)

這里寫目錄標題 0、驅動pytorch環境安裝驗證1.window環境2.Mac Apple M芯片環境 1、Nvidia顯卡驅動、CUDA、cuDNN關系匯總1**1. Nvidia顯卡驅動(Graphics Driver)****2. CUDA(Compute Unified Device Architecture)****3. cuDNN&a…

OpenWrt 搭建 samba 服務器的方法并解決 Windows 不允許訪問匿名服務器(0x80004005的錯誤)的方法

文章目錄 一、安裝所需要的軟件二、配置自動掛載三、配置 Samba 服務器四、配置 Samba 訪問用戶和密碼(可選)新建 Samba 專門的用戶添加無密碼的 Samba 賬戶使用root賬戶 五、解決 Windows 無法匿名訪問Samba方案一 配置無密碼的Samba賬戶并啟用匿名訪問…

CentOS 7鏡像源替換

更換為阿里云鏡像源(適用于 CentOS 7) 1、備份原來的 repo 文件: mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 2、下載阿里云的 CentOS 7 repo 文件: curl -o /etc/yum.repos.d/CentOS-Base…