零基础 go - 51(工厂模式入门)

3 阅读2分钟

go 的结构体没有构造函数,可以通过工厂模式来创建实例并初始化数据

由一个需求引出工厂模式

  • 我们都知道,定义结构体的时候,如果结构体的名字大写,是可以被其他包访问的;如果结构体的名字小写,则只能在当前包内访问。

  • 同样的,结构体内部的字段名如果是大写开头的,也可以被其他包访问;如果是小写开头的,则只能在当前包内访问。

  • 比如以下的 User 结构体,Name 和 Age 字段都是大写开头的,因此它们可以被其他包访问和修改:


type User struct {

    Name string

    Age int

}

  • 然而实际情况可能是这样的,结构体的命名和内部字段都是小写的,这样就无法直接在其他包中创建实例并访问字段了

  • 比如以下的 user 结构体,age 字段都是小写开头的,因此它们只能在当前包内访问和修改:


type user struct {

    Name string

    age int

}

  • 那如果我们非要使用这个结构体或者结构体内部字段呢?这时候就可以通过工厂模式来创建实例并初始化数据了

通过工厂模式来创建实例并初始化数据

main 包中需要访问 user 包中的 user 结构体,并且需要访问 user 结构体中的 age 字段。

使用工厂模式来实现这个需求

  • 1、在 user 包中定义 user 结构体

  • 2、在 user 包中,使用工厂模式 NewUser 来创建 user 结构体的实例

  • 3、在 user 包中,提供公共方法 GetAge 和 SetAge 来访问和修改 age 字段


package user

type user struct {

    Name string

    age int

}

func NewUser(name string, age int) *user {

    return &user{

        Name: name,

        age: age,

    }

}

// 通过公共方法访问 age 字段

func (u *user) GetAge() int {

    return u.age

}

// 通过公共函数访问 age 字段

func GetUserAge(u *user) int {

    return u.age

}

// 通过公共方法修改 age 字段

func (u *user) SetAge(age int) {

    u.age = age

}

// 通过公共函数修改 age 字段

func SetUserAge(u *user, age int) {

    u.age = age

}

  • 4、在 main 包中调用工厂模式来创建 user 结构体的实例

  • 5、在 main 包中调用公共方法和公共函数来访问和修改 age 字段


package main

import (

    "fmt"

    "user"

)

func main() {

    u := user.NewUser("Alice", 30)

    fmt.Println("Name:", u.Name) // 可以直接访问 Name 字段

    fmt.Println("Age:", u.GetAge()) // 通过公共方法访问 age 字段

    fmt.Println("Age:", user.GetUserAge(u)) // 通过公共函数访问 age字段

    u.SetAge(31) // 通过公共方法修改 age 字段

    fmt.Println("Age:", u.GetAge()) // 通过公共方法访问 age 字段

    user.SetUserAge(u, 32) // 通过公共函数修改 age 字段

    fmt.Println("Age:", user.GetUserAge(u)) // 通过公共函数访问 age字段

    fmt.Println("Name:", u.Name) // 输出 Alice (可以直接访问 Name 字段,因为 Name 字段是大写开头的,可以被其他包访问和修改)

    u.Name = "Bob" // 可以直接修改 Name 字段

    fmt.Println("Name:", u.Name) // 输出 Bob ( 可以直接访问 Name 字段)

}