Like Share Discussion Bookmark Smile

J.J. Huang   2025-04-19   Getting Started Golang 06.介面   瀏覽次數:次   DMCA.com Protection Status

Go | 使用介面實作記錄功能

💬 簡介

在開發應用程式時,記錄功能(Logging)通常是非常重要的部分,用來追蹤程式運行狀況、錯誤、警告等信息。在 Go 語言中,我們可以使用介面來實現不同的記錄方式,讓記錄功能更加靈活且可擴展。本文將示範如何使用 Go 介面來實作一個通用的記錄功能,支持多種記錄方式,例如:寫入文件、輸出到終端、發送到遠端服務等。

圖片來源:Gophers


🔍 記錄功能設計

📝 定義記錄介面

首先,我們定義一個 Logger 介面,這個介面將定義一個 Log 方法,所有的記錄方式都必須實現這個方法。

1
2
3
4
5
6
7
8
package main

import "fmt"

// 定義 Logger 介面,包含 Log 方法
type Logger interface {
Log(message string)
}

🖥 實現不同的記錄方式

接下來,我們為不同的記錄方式實現 Logger 介面。以下是幾個常見的記錄方式:

📄 寫入文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import (
"fmt"
"os"
)

// 定義 FileLogger 結構,表示寫入文件的記錄方式
type FileLogger struct {
file *os.File
}

// 實現 Logger 介面的 Log 方法
func (f FileLogger) Log(message string) {
f.file.WriteString(message + "\n")
}

// 建立一個新的 FileLogger
func NewFileLogger(filename string) (*FileLogger, error) {
file, err := os.Create(filename)
if err != nil {
return nil, err
}
return &FileLogger{file: file}, nil
}

🖨 輸出到終端

1
2
3
4
5
6
7
// 定義 ConsoleLogger 結構,表示輸出到終端的記錄方式
type ConsoleLogger struct{}

// 實現 Logger 介面的 Log 方法
func (c ConsoleLogger) Log(message string) {
fmt.Println(message)
}

🌐 發送到遠端服務

1
2
3
4
5
6
7
8
9
10
11
// 定義 RemoteLogger 結構,表示發送到遠端服務的記錄方式
type RemoteLogger struct {
remoteURL string
}

// 實現 Logger 介面的 Log 方法
func (r RemoteLogger) Log(message string) {
// 假設我們將訊息發送到某個遠端服務
// 這裡簡單模擬為輸出訊息到控制台
fmt.Printf("Sending to remote service at %s: %s\n", r.remoteURL, message)
}

🗜 使用介面進行記錄處理

現在我們可以根據需要選擇不同的記錄方式來實現記錄功能。這時候我們可以建立不同的 Logger 實例並統一呼叫 Log 方法來記錄訊息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package main

import (
"fmt"
)

func main() {
// 建立不同的記錄器實例
fileLogger, err := NewFileLogger("log.txt")
if err != nil {
fmt.Println("Error creating file logger:", err)
return
}
consoleLogger := ConsoleLogger{}
remoteLogger := RemoteLogger{remoteURL: "http://example.com"}

// 建立一個切片來存放不同的記錄器
loggers := []Logger{fileLogger, consoleLogger, remoteLogger}

// 使用不同的記錄器進行記錄
message := "This is a log message."

for _, logger := range loggers {
logger.Log(message)
}
}

輸出:

1
2
This is a log message.
Sending to remote service at http://example.com: This is a log message.

📝 此範例中,FileLogger 會將訊息寫入文件,ConsoleLogger 會將訊息輸出到終端,RemoteLogger 會將訊息發送到遠端服務。所有這些操作都統一通過 Logger 介面來執行,使得記錄功能非常靈活。

📄 查看文件記錄

如果您打開 log.txt 文件,應該會看到以下內容:

1
This is a log message.

📝 這樣的設計讓我們可以輕鬆切換記錄方式,甚至可以同時使用多種記錄方式,從而使得記錄功能更加靈活和可擴展。


🛠 優化:加入紀錄等級

在實際的應用中,我們通常會根據訊息的嚴重性來區分不同的紀錄等級,例如:INFOWARNERROR 等。為了更好地管理紀錄,我們可以將 Log 方法擴展為支持紀錄等級。

💡 增加紀錄等級

1
2
3
4
5
6
7
8
9
10
11
12
13
// 定義 LogLevel 型別
type LogLevel int

const (
INFO LogLevel = iota
WARN
ERROR
)

// 定義 Logger 介面,包含 Log 方法
type Logger interface {
Log(level LogLevel, message string)
}

🆕 更新各個記錄方式的實現

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 更新 FileLogger 實現,支持紀錄等級
func (f FileLogger) Log(level LogLevel, message string) {
levelString := getLogLevelString(level)
f.file.WriteString(fmt.Sprintf("[%s] %s\n", levelString, message))
}

// 更新 ConsoleLogger 實現,支持紀錄等級
func (c ConsoleLogger) Log(level LogLevel, message string) {
levelString := getLogLevelString(level)
fmt.Printf("[%s] %s\n", levelString, message)
}

// 更新 RemoteLogger 實現,支持紀錄等級
func (r RemoteLogger) Log(level LogLevel, message string) {
levelString := getLogLevelString(level)
fmt.Printf("Sending to remote service at %s: [%s] %s\n", r.remoteURL, levelString, message)
}

🔁 記錄等級轉換函式

1
2
3
4
5
6
7
8
9
10
11
12
13
// 根據紀錄等級返回對應的字串
func getLogLevelString(level LogLevel) string {
switch level {
case INFO:
return "INFO"
case WARN:
return "WARN"
case ERROR:
return "ERROR"
default:
return "UNKNOWN"
}
}

🗜 使用新紀錄等級進行記錄

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package main

import "fmt"

func main() {
// 建立不同的記錄器實例
fileLogger, err := NewFileLogger("log.txt")
if err != nil {
fmt.Println("Error creating file logger:", err)
return
}
consoleLogger := ConsoleLogger{}
remoteLogger := RemoteLogger{remoteURL: "http://example.com"}

// 建立一個切片來存放不同的記錄器
loggers := []Logger{fileLogger, consoleLogger, remoteLogger}

// 使用不同的記錄器進行不同等級的記錄
loggers[0].Log(INFO, "This is an info message.")
loggers[1].Log(WARN, "This is a warning message.")
loggers[2].Log(ERROR, "This is an error message.")
}

輸出:

1
2
3
[INFO] This is an info message.
[WARN] This is a warning message.
Sending to remote service at http://example.com: [ERROR] This is an error message.

📝 現在,我們的記錄系統支持不同的紀錄等級,這使得我們能夠根據嚴重性來分類和處理紀錄。


🎯 總結

通過使用 Go 語言的介面,我們實現了一個靈活的記錄功能,支持多種記錄方式(如寫入文件、輸出到終端、發送到遠端服務等)。此外,我們還可以根據需要擴展更多的功能,例如支持紀錄等級。這樣的設計使得記錄功能既靈活又可擴展,能夠輕鬆應對不同的需求。

透過這篇文章,我們學會了如何使用 Go 的介面來實作可擴展的記錄系統,這對於任何需要記錄功能的應用來說,都是一個非常有用的技術。

最後,建議讀者深入探索 Go 語言的介面特性,並將其應用於更多場景中。

最後建議回顧一下 Go | 菜鳥教學 目錄,了解其章節內容。


註:以上參考了
Go