面试题答案
一键面试单一职责原则在Go语言函数封装中的遵循方式
- 明确函数目的:每个函数应该有一个清晰、明确且单一的目标。例如,一个函数负责从文件读取数据,就不应该同时承担解析数据或处理业务逻辑的任务。
- 避免功能混杂:函数体内部代码逻辑应紧密围绕其单一职责展开,不应包含与该职责无关的代码。例如,一个计算数学平均值的函数,不应该在其中加入日志记录或数据库操作的代码。
- 保持函数短小:通常来说,实现单一职责的函数代码量不会过于庞大。如果函数代码行数过多,可能意味着它承担了多个职责,需要进一步拆分。
复杂功能拆分示例
假设我们有一个复杂功能,从数据库读取用户信息,然后根据用户信息生成报告并保存到文件。
package main
import (
"fmt"
// 这里假设使用的数据库驱动包
"database/sql"
_ "github.com/go - sql - driver/mysql"
"os"
)
// 模拟数据库连接
func getDB() (*sql.DB, error) {
db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/test")
if err != nil {
return nil, err
}
return db, nil
}
// 从数据库读取用户信息
func readUserInfoFromDB() ([]byte, error) {
db, err := getDB()
if err != nil {
return nil, err
}
defer db.Close()
rows, err := db.Query("SELECT * FROM users")
if err != nil {
return nil, err
}
defer rows.Close()
// 这里简单拼接数据,实际应用会更复杂
var result []byte
for rows.Next() {
var id int
var name string
err := rows.Scan(&id, &name)
if err != nil {
return nil, err
}
data := fmt.Sprintf("ID: %d, Name: %s\n", id, name)
result = append(result, []byte(data)...)
}
return result, nil
}
// 根据用户信息生成报告
func generateReport(userInfo []byte) []byte {
// 这里简单示例报告生成,实际会更复杂
report := fmt.Sprintf("User Information Report:\n%s", userInfo)
return []byte(report)
}
// 将报告保存到文件
func saveReportToFile(report []byte) error {
file, err := os.Create("report.txt")
if err != nil {
return err
}
defer file.Close()
_, err = file.Write(report)
if err != nil {
return err
}
return nil
}
func main() {
userInfo, err := readUserInfoFromDB()
if err != nil {
fmt.Println("Error reading user info:", err)
return
}
report := generateReport(userInfo)
err = saveReportToFile(report)
if err != nil {
fmt.Println("Error saving report:", err)
return
}
fmt.Println("Report saved successfully.")
}
在上述示例中,原本一个可能很复杂的功能被拆分成了 readUserInfoFromDB
、generateReport
和 saveReportToFile
三个函数,每个函数都遵循单一职责原则,分别负责从数据库读取用户信息、生成报告以及保存报告到文件。这样使得代码结构更清晰,易于维护和测试。