工厂模式详解|学习笔记

简介: 快速学习工厂模式详解

开发者学堂课程【Go 语言核心编程 - 面向对象、文件、单元测试、反射、TCP 编程:工厂模式详解】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/626/detail/9685


工厂模式详解

 

内容介绍:

一、工厂模式的说明

二、工厂模式的需求

三、选择使用工厂模式实现跨包创建结构体实例(变量)的案例

四、思考题

 

一、工厂模式的说明

Golang 的结构体没有构造函数,通常可以使用工厂模式来解决这个问题。换言之,工厂模式就相当于是构造函数的功能。

 

二、工厂模式的需求

一个结构体的声明如下所示:

package model

type Student struct {

Name string...

}

因为这里的 Student 的首字母s是大写的,如果我们想在其它包创建 Student 的实例(比如 main 包),引入 model 包后,就可以直接创建 Student 结构体的变量(实例)。但是问题来了,如果首字母是小写的,比如是 type student struct {}此时就不可以在其他包进行引用,而更多情况下我们希望首字母是小写的,并且希望结构体可以在其他包中使用,这时就需要引用工厂模式来完成上述需求。

 

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

1.如果 model 包的结构体变量首字母大写,引入后可以直接使用。

在 chapter10 中新建一个文件夹,命名为 factory ,然后再在该文件夹下创建两个文件,一个是 main 文件,一个是 model 文件。在 model 中新建一个文件student.go,在里面输入 model 包(package model),定义一个大写的结构体 Student。结构体中有两个字段,学生的姓名(Name)以及考试的成绩(score),分别是 string 类型和 float64类型。定义完成后保存,进入 main 包后引入 student 包后可以直接调用,代码为 package main import("fmt""go_code/chapter10/factory/mode1")。然后定义一个主函数(func main()),并创建一个创建一个Student的实例(变量),代码为:var stu=mode1.Student{,此时直接写入Name : "tom",Score :78.9,即可完成赋值,例如学生姓名为tom,他的考试成绩是78.9,调用后发现输出结果=为汤姆78.9,与理论结果一致。但是此时的问题是如果说如果student是小写,再在main包中调用时,只将main包中的相应代码改为小写,不能实现调用,而且将会报告该变量不可导出。

核心代码:

package model

//定义一个结构体

type student struct{

Name string

Score float64

}

package main

import (

"fmt"

"go_code/chapter10/factory/mode1"

)

func main(){

//创建一个 student 实例

var stu=mode1.Student{

Name : "tom",

Score :78.9,

}

fmt.Print1n(stu)

}

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

在 student.go 文件中将结构体类型进行更改,全部改成小写模式,更改之后 main 文件中的相应代码就会报错,即不能够在main文件中使用了(因为 student 结构体首字母是小写,因此是只能在 model 使用)。解决方案是:在 student.go 文件中引入工厂模式,首先给 student 写一个方法,该方法要求可以传入两个参数,一个是名字(n,string 类型),一个是成绩(s,float64)float,最终要要返回的类型是一个指针,代码为:func Newstudent(n string, s float64)*student {

返回时直接 return &student{,因为小写字母开头的结构体变量是可以在本包中使用,然后进行初始化(Name : n,score : s,),返回再看相当于在这个文件里面创建了一个student的对象实例然后返回,但是返回的时候是指针类型,这就意味着在其他包进行调用的时候,就是返回的数据本身。可以理解成这个数据空间是放在一个堆里面的,共享一个空间。写完之后进行全部保存,再在 main 文件中进行调用就会十分方便了,对main文件中的代码进行改进,完成对 student.go 文件中方法的调用,而且要把学生的信息传入进去,输入 var stu = model. Newstudent( "tom~",88.8)完成调用。实际上这个地方返回的是student的指针,所以在输出的时候也会出现信息前面加有&,运行后发现的确是这样的。对于student的信息,也是可以取出的,只需要在输出代码中添加*即可,即输出代码为:fmt.Print1n(*stu)fmt.Print1n("name=", stu.Name, " score=", stu.score)。这是因为虽然是指针,但是golang编译器底层会进行优化。

核心代码:

l student.go

package model1

//定义一个结构体

type student struct{

Name string

score float64

}

//因为student结构体首字母是小写,因此是只能在model使用,我们通过工厂模式来解决

func Newstudent(n string, s float64)*student {

return &student{

Name : n,score : s,

}

}

l main.go

package main

import(

"fmt"

"go_code/ chapter1e/factory/model"

)

func main(){

var stu = model. Newstudent( "tom~",88.8)

fmt.Print1n(*stu)

fmt.Print1n("name=", stu.Name, " score=", stu.score)

}

四、思考题

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

思路:

如果把 Student 里面的 Score 改成小写的 score,保存后会发现会报错,改成小写以后成为不可导出的字段,因为现在是小写的,那么给 student 的结构体指针绑定一个方法并返回s,就可以解决问题。如果 score 字段首字母小写,则在其他包不可以直接访问,这时候我们可以提供一个方法.给 student 结构体指针绑定一个方法GetScore,然后返回放float64,代码为:func (s*student) Getscore( float64{,输入return s.score返回。在这个包里面,s可以去访问score。因为小写字母就可以访问自身包的字段。输出方式为:fmt.Print1n("name=", stu.Name " score=", stu.GetsSore)。因为方法是大写的,所以说方法本身是对外公开的,因此可以通过一个对外公开的方法去访问到私有的,或者不可导出的字段。

核心代码:

l Student.go

package model

//定义一个结构体

type student struct{

Name string

score float64

}

//因为 student 结构体首字母是小写,因此只能在 model 中使用,可以通过工厂模式来解决

func NewStudent(n string, s float64)*student {

return &student{

Name : n,

score : s,

}

}

//如果 score 字段首字母小写,则在其它包不可以直接方法,此时我们可以提供一个方法,使其可以在其他包中使用。

func (s *student)Getscore() float64{

return s.score

}

l Main.go

package main

import (

"fmt"

"go__code/ chapter1e/factory/model"

)

func main(){

var stu = mode1。Newstudent( "tom~",98.8)

fmt.Print1n(*stu)

fmt.Print1n("name=", stu.Name, " score=", stu.Getscore())

}

相关文章
|
5月前
|
设计模式 XML Java
【设计模式】第三篇:一篇搞定工厂模式【简单工厂、工厂方法模式、抽象工厂模式】
三 结尾 如果文章中有什么不足,欢迎大家留言交流,感谢朋友们的支持! 如果能帮到你的话,那就来关注我吧!如果您更喜欢微信文章的阅读方式,可以关注我的公众号
54 5
|
设计模式 C#
c#设计模式-创建型模式 之 工厂模式
工厂模式(Factory Pattern)是一种常用的对象创建型设计模式。该模式的主要思想是提供一个创建对象的接口(也可以是抽象类、静态方法等),将实际创建对象的工作推迟到子类中进行。这样一来,客户端只需关注接口而无须了解具体的类实现,实现了代码的解耦,提高了系统的可维护性和扩展性。工厂模式可以分为简单工厂模式,工厂方法模式和抽象工厂模式。简单工厂模式:又叫静态工厂方法模式,它是由一个工厂对象决定创建出哪一种产品类的实例,但它不属于工厂模式家族,它属于创建型模式,但不属于23种GOF设计模式之一。
41 1
|
设计模式
设计模式系列教程(05) - 工厂模式
设计模式系列教程(05) - 工厂模式
48 0
|
设计模式
设计模式关于工厂方法学习总结
设计模式关于工厂方法学习总结
55 0
|
设计模式 C++
【设计模式学习笔记】简单工厂模式、工厂模式、抽象工厂模式案例详解(C++实现)
【设计模式学习笔记】简单工厂模式、工厂模式、抽象工厂模式案例详解(C++实现)
339 0
【设计模式学习笔记】简单工厂模式、工厂模式、抽象工厂模式案例详解(C++实现)
|
设计模式 C++
【设计模式学习笔记】建造者模式和原型模式案例详解(C++实现)
【设计模式学习笔记】建造者模式和原型模式案例详解(C++实现)
285 0
【设计模式学习笔记】建造者模式和原型模式案例详解(C++实现)
|
设计模式 搜索推荐
【设计模式】-创建型模式-第2章第2讲-【工厂模式】
【设计模式】-创建型模式-第2章第2讲-【工厂模式】
【设计模式】-创建型模式-第2章第2讲-【工厂模式】
|
安全 PHP 开发者
工厂模式|学习笔记
快速学习工厂模式。
工厂模式|学习笔记
|
设计模式 Java 关系型数据库
工厂方法模式 | 学习笔记
快速学习工厂方法模式
|
设计模式 关系型数据库 Scala
简单工厂模式 | 学习笔记
快速学习简单工厂模式