go_工厂模式

说明:

Golang 的结构体没有构造函数,通常可以使用工厂模式来解决这个问题。

有一个这样的需求:

一个结构体的声明是这样的:

package model

type Student struct { Name string...

}

因为这里的Student 的首字母S 是大写的,如果我们想在其它包创建 Student 的实例(比如main 包), 引入 model 包后,就可以直接创建 Student 结构体的变量(实例)。但是问题来了,如果首字母是小写的, 比如 是 type student struct {....} 就不不行了,怎么办---> 工厂模式来解决.

使用工厂模式来解决问题

  • 使用工厂模式实现跨包创建结构体实例(变量)的案例:

如果 model 包的 结构体变量首字母大写,引入后,直接使用,  没有问

student.go 

package model

//定义结构体
//当结构体名称的为首字母大写时,可以被外部的包调用
type Student struct {
	Name  string
	Score float64
}

 main.go

package main

import (
	"fmt"
	"go_code/factory/model"
)

func main() {
	//创建Student实例
	var stu = model.Student{
		Name:  "tom",
		Score: 89.7,
	}
	fmt.Println(stu)
}

 如果 model 包的 结构体变量首字母小写,引入后,不能直接使用, 可以工厂模式解决

 student.go

package model

//定义结构体
type student struct {
	Name  string
	Score float64
}

//因为student结构体首字母小写,因此只能够在当前包model中使用
//这时我们可以通过工厂模式来解决
//写一个工厂模式的函数,相当于构造函数
func NewStudent(name string, score float64) *student {
	return &student{
		Name:  name,
		Score: score,
	}
}

 main.go

package main

import (
	"fmt"
	"go_code/factory/model"
)

func main() {
	//创建Student实例
	// var stu = model.Student{
	// 	Name:  "tom",
	// 	Score: 89.7,
	// }

	//当student结构体为首字母小写时,我们可以通过工厂模式来解决
	var stu = model.NewStudent("tom", 86.7)
	fmt.Println(*stu)
	fmt.Println("name=", stu.Name, "  score=", stu.Score)
	//fmt.Println("name=", (*stu).Name, "  score=", (*stu).Score)
}

 思考题:

如果 model 包的 student 的结构体的字段 Score 改成 score,我们还能正常访问吗?又应该如何解决这个问题呢?

 student.go

 

package model

//定义结构体
type student struct {
	Name  string
	score float64
}

//因为student结构体首字母小写,因此只能够在当前包model中使用
//这时我们可以通过工厂模式来解决
//写一个工厂模式的函数,相当于构造函数
func NewStudent(name string, score float64) *student {
	return &student{
		Name:  name,
		score: score,  //其他包不能直接访问
	}
}

//如果score字段首字母小写,则,在其他包中不可以直接访问,我们可以提供一个方法
func (s *student) GetScore() float64 {
	return s.score
}

main.go

package main

import (
	"fmt"
	"go_code/factory/model"
)

func main() {
	//创建Student实例
	// var stu = model.Student{
	// 	Name:  "tom",
	// 	Score: 89.7,
	// }

	//当student结构体为首字母小写时,我们可以通过工厂模式来解决
	var stu = model.NewStudent("tom", 86.7)
	fmt.Println(*stu)
	fmt.Println("name=", stu.Name, "  score=", stu.GetScore())
	//fmt.Println("name=", (*stu).Name, "  score=", (*stu).Score)
}

关于这个代码的注意事项:

  1. 关于大小写

    • )小写字母开头的函数只在本包内可见,大写字母开头的函数才能被其他包使用。这个规则也适用于类型和变量的可见性。

    • )大小写影响了可见性,大写字母开头等同于public,小写字母开头等同于private,这种做法不仅免除了public、private关键字,更重要的是统一了命名风格。

  2. 结构体方法参数

    • )如果要求对象必须以指针传递,这有时会是个额外成本,因为对象有时很小(比如4字节),用指针传递并不划算。

    • )只有在你需要修改对象的时候,才必须用指针。

更多资料参考: Go设计模式(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值