00:00
我们来看一下,在go浪里边面向对象的时候呢,有一个叫工厂模式,我们给大家做一个介绍,首先我们说一下这个工厂模式什么时候可能用得到,我们先看一个说明,高浪的结构体里面没有构造函数,这一点大家注意一下。也就是说我们在面向对象里边呢,没有这个构造函数这个说法了。以前我们在学别的传统的编程,面向对象编程的时候,大家都知道我们要获取到它的一个实例,我们是怎么做的呀,我们是通过构造函数来获取的,对不对?但是呢,在go浪里面,它没有构造函数这一说,因为我们知道,呃,Go的结构体就类似于别的编程语言里面的class。那么这个结构体没有构造函数,那么我们怎么去获取到一个结构体的实例呢?它是这样子的,通常我们使用工厂模式来解决这个问题,换言之,你可以简单的理解成工厂模式,就相当于是以前构造函数的功能。理解这意思吧,好,我们先把这个,先把这个说明说到这啊,那么嗯,那看一个需求吧,什么时候我们可能用到工厂模式呢。
01:09
大家看现在呢,有一个结构体,它的声明是在model包里边儿。他在猫包里边,那么类型是type student structure。Name string,好,当然还会有其他字段,注意听这里说啊,Student首字母,现在我们是不是大写的?是不是大写的,因为说因为这个student首字母是大写,因此如果我们要在其他包创建student的对象实例,比如说面包里面,其实我们只需要引入这个model包,实际上我们就可以解决这个问题。我直接用,我直接我直接去创建一个student就行了,对不对,但是有一个问题。但是问题就来了,那假设我们这个首字母变成小写了呢?各位想一想,如果我把这个student在定义它的这个结构体变量时,结构体类型时,我们把它写成小写的,那你想如果你把它写成小写的,那么你在这个面包里面其实就用不了,就创建不了这个对象实例了,是这意思吧?
02:10
没问题吧,肯定是你是用不了了,可是我们通常情况下都会去用,我们既希望它的名称是首字母是小写的,同时我们还希望在别的包去创建一个student的实例,那又怎么办呢?这时我们就需要工厂模式来解决,能理解这意思吧?好,我们先来把这个需求已经说清楚了啊,就是什么时候用到这个工厂模式呢?就是当我们这个结构体手定义的时候,他手中的是小写,但是呢,我们又需要在别的包里面去创建这么一个结构体类型的实例。这个时候工厂模式就能发挥它的作用啊,就是用它来处理这个事情,好,我们先把这一块的分析呢,整理到我们的笔记里边去,好这地方讲的是工厂模式。
03:01
好的,我先把它整理一下。下面呢,我们接着说好吧,首先我们对它做了一个说明,没问题吧,我们对它做一个说明,好,这个说明我们来一个标题三吧。说明诶。标题三还没有给我发生变化,对不对?标题三好这块呢,有一个需求,我们也来一个标题三,对不对板述一下。好,没问题。好,那现在呢,我们的问题已经提出了啊,提出是从哪提出来,是这提出来的。就这句话。但是问题来了。从这开始,提出了我们一个需求,就是如果首字母是小写。这个S是小写,那么我们在别的包里面就用不了,这是工厂模式就出来了,引出这个问题了,对不对?好,那么我们现在就来开始举例说明这个事情,大家看我的幻灯片,大家看这里,那么工厂模式来解决这个这个前面的问题。解决解决问题,那使用共同模式实现跨包创建结构体实例的案例就来了,我们呢,这样子说啊,这个model这写错了,Model这样写才对。
04:10
对吧,好,我们来先构建这么一个案例,构建一个项目来讲这个东西听我讲啊,这块很重要,那打开我们这块呢,我们我们新建一个包包。对吧,我们新建一个文件夹。这个文件夹我们就叫factory。Factory这个工厂模式嘛,工厂模式factory就叫factory就行了,然后呢,我新建在下面再建两个文,两个包一个诶再建两个文件夹,一个是main,一个是什么呢?比如说model。Model OK来了,那首先呢,我在这个model里面创建了一个文件叫student,能跟上老师思路啊,点go。没问题吧,在这里面我打一个包包,Package。那么我打一个包,这个包叫model。
05:02
OK,呃,Model,然后呢,我们这个地方呢,就定义定义一个这个结构体。好,我们先定一个大写的,大家先体验一下,比如说这有个student对不对。那么它是一个结构体。它的类型里面有两个字段。Name。比如说。对吧,我们再来这个学生呢,他有一个,呃,比如说这个学生上,呃,他有一个考试的成绩考。64换一个啊好这样子大家看清楚了,那这个时候我定义完了过后呢,我们保存一下。保存保存完了,现在我在main包里边,注意听我在面包里面要去用它,这个时候大家想是不是我我是没有没有什么。就是就是几乎说我就直接用就行了,对吧,没有什么麻烦,我就直接package。Package面包。
06:01
然后呢,我们这边import一下不卖。然后我们定义一个主函数。Function me。来这里我们创建一个,创建一个ST的。实力。其实就是变量啊,同学们,那这个时候其实很简单,你就直接这样写就可以了,是不是跟刚才老师这样写没有任何没有任何问题,我直接就给他了,那就student。那name。好,给他一个名字叫汤姆,没问题吧,然后再给他一个score,他的考试成绩呢,比如说是78.9,那我们输出一下,看看有没有问题。Print,哎,对不起,这写错了,咱们这写错了啊,这样写肯定是错的,为什么呢?因为你连包都没有引这个地方,我们先看看它会报什么错好不刚好顺带就把这个一起讲了,大家看,我们保存完了之后,他马上就报了一个错,那这帮事没有少。
07:00
一个这个啊,大家看。我们看这还会报什么错误没有?大家看这报错了,说on five student肯定没有啊,你都没有定义,那怎么办呢?引爆引包的时候我们用这样引法。好,还是这样用这个比较方便的语法啊。统一用一个括号括起来。对不对,那引包的时候大家还记不记得怎么引,是不是从这个src这个目录开始引呢?还记得吧,S从src这个目录下面开始就够。Cold。扣是不是,然后呢,咱们在引包的时候是。这样引就行了,写上它是chapter。CHAPTER10,再往下面写有一个Y。Factory这个。好,最后写到这个,我们的model。对吧,保存一下。对不对,保存过后,我们看到它这个地方是,哦哦,这个顺序咱们是不是写反了呀。
08:02
斜杠应该这样写对不对?因为这样写才对。再来这个时候它会提示我们没有用过,对吧,大家看是不是没有用到啊,但是没有用,没有用是因为我这没写,怎么用呢?Model mode点。因为你你把这个是打在这个包包里面的吧,这样用就没问题了。这个大家能理解吧,就是你这个model这个包里边有一个定义的16的这个结构体,那我这样用是没码没有问题,而且我也隐包了,那这个时候我们来输出肯定代码是OK的。那我们CD到factor里面去,没问题吧,Go running,命点go跑起来我们可以看到。点go哦,我们还得到里面去,是不是我们还到这个包里面去才能运行go run main.go没问题吧?这时我们看输出的结果,输出结果就是汤姆78.9没问题,跟我们定义的是一样的,但是问题来了。
09:01
但是问题来了,在哪里,同学们看,如果说如果说我这个student,它这个是小写的,因为有有些有些情况下我就是要小写,因为我就我就希望什么呢?他有个封装性,当我一旦把它小写的时候,大家可能会想到我把这个地方也改成小写,但是显然这地方会报告这个变量是不可导出的,大家看这里他写了一个什么。On,这为什么呢?他是不可没,他说,Cannot refer to。这个值UN unexported就是不可导出。因为你你这个小写的就是私有的,你在别的包里面是用不了的。那问题就很严重了,你这样用就已经创建不了这个对象实例了,是这意思吧。OK吧,好,这个问题我们已经抛出来了,来,再来看。工厂模式解决的问题,我们把它稍微的整理一下,跟上老师思路。好,那这个问题呢,是怎么提出来的,就是使用工厂模式,诶大家看,如果我直接这样用。
10:07
对吧,使用工厂模式,我们这把整理一下。诶,好,我把这稍微的板述一下啊,如果model包里面的结构体首字母是大写,引入后直接使用没有问题,比如说刚才老师这样写就是OK的,怎么写的呀?注意听啊,我在这儿是大写的,然后在这个main里面,这儿也是一个大写的,肯定就是OK的。对吧,我保存一下代码没毛病,好,我把这个没有没有问题的,诶这为什么还是报错。为什么还是包错呢?全部保存是不是?就好了,诶对应该是全部保存啊好,那大家看啊,我们这里面定义了一个文件。我把这段代码给他板述一下好不好,大家不要着急啊,这块比较重要。我把它板书一下。这块。
11:01
对吧。这这个model包里面有一个student,然后呢,我们在用的时候正确使用。这个是正确的。这样用是没毛病的,大家看这里。对吧,诶,同学们看到我在这把它。一下。对不对,好,这个是OK的,这样用,为什么,因为你S是大写的。S大写,所以说这这种代码它就过了。没有一点问题,我把它稍微的。放小一点,它就放到上一行了,对不对,这样代码就整在一起了,好没有问题,现在是没有问题的啊,因为你这个引入的结构体变量大写引入后直接使用没有问题。现在问题在哪里呢?在下一个幻灯片大家看,如果使用工厂模式的案例呢?如果model包的结构结构体。首字母是小写,引入后就不能直接使用,可以使用工厂模式来解决好,同学们,现在呢,我给大家马上解决一下这个问题。
12:01
好。我们来把它处理一下,怎么处理这个事情呢?使用工厂模式。现在我把它全部改成小写。首先大家看这里,我先把它改成小写的S,显然当我把它改成小写S过后呢,这段代码肯定是要报错的,对吧,你把它保存一下,它就报错了,稍微动一下啊。动一下,他马上报错。因为他说这个是没有定义过的吗。好是吧,所以这个这个代码已经不能用了,那不能用怎么办呢?我们这地方就这样写。注意听,因为STU这个这个结构体。首字母。首字母是小写。消息因此是相当于是私有的了,因此是私有的只能在啊,因此只能。智能。只能在model包使用。使用。猫包使用啊。
13:02
使用。那现在呢,我们怎么解决这个问题呢?这样子做,我们这样做啊,我们通过通过工厂模式。工厂模式来解决这个问题。怎么解决,大家看我的代码。好,大家看我在吗?我我给他写一个方法。我给这个student写一个方法,我们方法不是白学的,对不对,我们学了肯定要用,怎么写呢?那就这样写。我们返回一个,呃,我们首先是给他绑定,所以说这是一个S。哦,ST。STDT没问题吧,但是呢,我给它绑定是一个指针,指针形式就是给它放成一个指针,到时间它返回一个指针就行了。呃,我看看啊,这样不需要给他绑定,直接写个写个方法也可以,直接写个方法也行,对不对,写个方法应该更简单,这样我们先我们就直接写个方法,就不这样麻烦了,直接写个方法叫六。
14:03
六一个什么呢?Student对不对,六一个student,我们我们这个六一个student,让他返回一个什么呀,让他给我传入,给他给我传进来两个参数,就是一个是名字,一个score,那我让他传一个值进来,比如说name。啊,这个name值就看你怎么写这个变量,比如说N对吧,N是正类型的对不对,还有个SS呢是一个float。六四的类型。然后我到时要返回的类型呢,是一个指针。注意听,我要返回的是就点,因为你返回这个东西,就相当于说你在这里面创建过直接返回,返回的就是一个指,指向你这创建的这么一个结构体的数据空间。那这直接return什么呢?我们前面学过这个吧。这个大家还有印象啊,Return一个指针,因为你这个16是小写的,我在本包使用是没有问题的,那我就给它初始化了,怎么写呢?那传进来就是你这写的N。
15:08
你给我传是什么,我就给你创建这个16吨的对应的这个结构体的变量,好还有一个score。好,这个SC呢,就是你传进来是什么分数,我就给你放进去,完事返回,大家看是不是就相当于说你在这个文件里面创建了一个student的对象实例,然后给他返回,但是你返回的是指针,那就意味着在别的地方用的时候,就是你返回的这个数据本身,因为你返回的是指针吗?那你可以认识,你也可以理解,相当于说这个数据空间是放在一个堆里面的,它是共享的一个空间,大家都可以用。明白我的意思吧。好好,大家看看能不能理解,那写完了过后,那我在这边用的时候是不是就非常方便了,我就不要这样去写了,我把这个代码进行一个改进。注意听前面还是一样的,当。
16:04
当sto这个结构体,结构体是首字母小写。小写。我们可以这样,我们可以这是通过我们可以通过工厂模式来解决。那你通过工厂模式来解决,其实说白了就是掉了一个方法,你你看你这个方法本身是不是,它其实是一个。收这么大写的,那你可以用它,那这样解决就可以了,你看啊,我还是用SQ。等于什么呢?Model包里面的这个函数。当然,我要把这个学生信息传进去,你不是要汤姆吗?好,那我就给他传一个汤姆进去。那么为了以示区别,我传一个汤姆波浪号,好吧,然后成绩88.8。好,你看这样子,我在我在做这样子,就相当于说使用到了什么呀,这个东西大家看这里unde model new student是不是没保存呢。
17:06
全部保存。好,全部保存这块没问题了,再看这面是有什么问题没有N好,这面是不是少写逗号啊?对不对,好代码就OK了。这样就通过工程模式,我们也拿到一个student的一个实例,但是大家想因为你返回的是指针,那我问大家实际上这个地方返回的是student指针还是student这个这个结构体变量呢?显然,这也是个指针。所以你在输出的时候呢,这样输出他也会有一个这样的信息,前面有个定时符,然后这里面一堆信息是是这样子的吧。对不对,好,我们来先运行一下。我们来运行一下,跑起来,我们看一下结果。我们可以看到的确是这样子的,那也就是说你在这个地方拿到的这个呢,就是你这个new student给他在他这个函数里面创建的这么一个对象实例。
18:03
那不管怎么,你是可以用的了。啊,你是可以用的,因为你在这里面创建了吗?创建过后你又返回给我,那我就用它对不对,那你在取值的时候依然可以一样取,就说你要取值的时候,你可以这样子。我告诉大家怎么取啊,来,跑起来。你加一个。呃,这是写错了,不能这样写,要用这个取值对不对,这样就把它整个全部取出来了。大家说这个地址是不是就是里面那个地址啊,啊,就是那个对那个student实例的地址,你看就取出来了,同样我们也可以把他的其他信息都取出来print,好我们取一下啊,Name等于。那你完全可以这样写点name,为什么我们说这样可以也可以取,因为虽然你是指针,但是呢,我们知道这个编译器底层它在去对指针访问它属性的时候呢,呃,访问它字段的时候呢,它也在前面会默认加一个这样的字,是吧,其实标准写法还是这写法,但是呢,因为编译器它做了处理,这样写也是可以的,也没有问题,明白吧,好,我们把它的这个score也输出来。
19:09
等于好也数出来怎么写Sq.qre写完了。跑起来。大家看。是不是信息也取到了,大家看这里。对吧,名字是汤姆是克88.8。好,那么我们就在这里呢,使用了我们的工程模式来解决了一个首字母,就是别的包,它的结构体是首,首字母是小写的这个问题,怎么拿到在不同的包里面去拿到它的一个对象实例的问题,明白好,那现在呢,我把这一块给他整理到这里去。怎么解决的啊,看代码。代码说明。具体来说呢,其实我就是这做了一些改进而已,第一个呢,在这个包包里面,在model这个里面。巴字尼夏在这里。
20:00
是不是我们增加了一个方法?这个就叫工厂模式,对不对?工厂模式我们增加了这个方法,后面我们还会写的更严谨一点。好把整理到这,然后呢,为了好看,我把它缩小一点。放在一起,另外在他的这个别的包里面,我们是怎么用的呢?在面包里面我们是这么用的。看清楚了。我就把它放在一起好吧。再看这里使用的时候呢,是这样用的。没问题吧,关键点就在这儿。但是我要再次强调啊,这个sto它其实是指向结构体的一个指针,因为你返回的就是就是一个指针嘛。对不对,那所以说我在这呢,再说明一下。好,我把这个呢放小一点。好,把它放到这就可以了,大家看能看懂吧。好,可以看懂啊,也不是很难对吧,这是一个文件,这是文件对不对,两个文件,好,这个文件是,呃,干脆我这大家应该能看懂,这个也不难,对吧,这是呃,这是那个这个文件的名字我们写一下。
21:09
啊,这样子啊这样子。呃,为了板书好,还是把它。稍微的。稍微的板一下啊。这样可能大家看的可能是有点儿不太容易看懂。好缩小一下,这个呢,我写一个文件名字,这个文件名字就是我们的这个student。点购对不对,反正源代码也会给大家,只是我在这说的再清楚一点。对吧,说再清楚一点。不要小看笔记啊,有时候很多同学写完了过后都不知道老师曾经讲过什么东西,所以板书呢,稍微板的清楚一点,好,大家看这里好,那现在呢,呃,关于这个工厂模式的基本使用,我们就说到这儿,大家应该也清楚了,对不对?那么关于这个地方,我再强调一点,这。
22:02
大家看这里。还有一个思考题留给大家,大家想一想。同学们思考一下,如果model包里面student结构体的字段这个。哎,当然我这原先有个age,那我就把它改成这个吧,就是如果这有个score。我们把它改成小写的。大家想想,这个问题很严重了,SC,请问我们还能正常访问吗?大家想一想啊,如果我把这个地方。把student里面这个S改成小写的S,但你这改成小写S,你这肯定要改,这是肯定的。对吧,你把它改成小写S,这个时候你保存,你们会发现这边又会报错,哪里会报错。保存一下。大家看这地方一定会报错。你看啊,他说sto点这个,这个现在还没错,还没报错是吧,我们运行一下它就会报错,他有时有时候反应比较迟钝。大家看我这,咱们看这里已经报错了。
23:02
大家看没有,他说新点models has no fair什么什么score,对吧,但but,他说没有这个,没有这个字段,没有大写的s score but does have,但是有一个小写的,大家看这已经报错了,那我把它改成小写的,你觉得你能用吗?你改成一个小写的,他马上就会告诉你这个是不可导出的,看到没有,他说student.go on,他说你没有定义。Cannot,为什么呢?他说,Cannot不可以指向一个UN exported就是不可导出的一个字段。因为你这个是小写的嘛,那就是用不了。那这个问题怎么解决啊,同学们。哎,我问大家一个问题,你们能解决吗?其实老师刚才讲的这些东西,大家应该如果你听懂的话,你稍微改一改就知道了,既然你这个是一个小写的对不对,你你已经是个小写的了吧。大家都知道说老师我这我这地方是一个小写的,那你既然是小写的,你能不能在这个student这个上面给他绑定一个方法。
24:07
就给这个指针绑定一个方法,让他返回这个A呢,这是完全可以做到的,做得到的吗?好,我来给大家解决一个问题啊,如果。注意听。如果注意听啊,如果我们这个score。思考。字段。首字母首字母小写。消息则。在其他包则在其他包,其他包不可以,不可以直接访问。不可不可以啊,包不。可。可以直接访问。那这时候我们可以提供一个方法。注意听。我们可以提供。提供一个方法来解决,那这个方法呢,我们这样写怎么写呢?Fun注,我们就写S新student。
25:08
对不对,我给他这个结构体指针绑定一个方法,这个方法呢,我们就叫get。盖的什么呢?考这个没有没有问题吧。好,然后盖K呢,我就返回它的这个FLOAT64。OK,然后呢,我怎么访问SDR?SC,诶,我问大家一个问题,在这个包包里面,在这个包包里面,我我这个这个S区访问,访问小写的score可不可以,这方是肯定可以的,为什么肯定可以,因为你本身。你你本身是在这个包里面的,我把我访问本包的一个字段名字,虽然你是小写的,我是也是有权利访问的,对不对,所以这就没问题了,这写完了,写完过后我们要输出这个值的话,我们就应该这样去输出了,Get。
26:00
什么SC?写完了考你这个方法,因为你get score这个方法呢,在这面是大写的,所以说这个方法本身它是对外公开的,对吧,因此我可以通过他写的一个对外公开的方法去访问到他的一个私有的,或者说不可导出的一个。字段没问题吧,现在我把它全部保存,你看代码就OK了。大家看这里。是不是就可以了,而且你看刚才我们老老师是不是讲过这个人为什么写范。Field,我看这地方是为什么啊?Get,难道我这个名字写错了吗?好,我把这个再重新来一下。好,我把它重新粘贴一下啊。好单词应该是刚才写错了SSCSC,好这个就没没错了啊,但是你要明白这个SQ还是指针哦,这个指针去调用它的一个方法,因为你这给这个指针绑定一个方法,因此刚才老师讲了一个特别重要知识点,就这个地方S,它到底是指拷贝还是地址拷贝,主要是取决于那个这个参数对不对,他传过来个这个S,我问大家这个S是不是就是你这个student。
27:25
肯定就是它,因为它是指针传递。它是它是一个指针传递,那就是只拷贝,呃,那就地址拷贝拷贝过来,我在这个底地这个里面去取出它的S也是可以的,但是实际上这个标准写法也应该是这样写。因为它是指针,同样道理,我们没有这样写,是因为底层它做了一个简化处理,好同学们,我们来看看这个时候能不能正确的访问到我们这个,靠。好,为了看到有有区别呢,我把这个纸稍微改一下,叫98.8明白,好同学们,我运行一把,请看效果。我们可以看到代码也是没有任何问题的,看到没有。
28:02
所以说在这里呢,我们就讲了这个工厂模式,以及给大家讲了一个如何去访问一个结构体的字段,是私有的。一个方法。其实这个呢,就是go里面的一种封装的一种方式啊,后面呢,我们在写代码的时候还会遇到类似的这种写法,大家一定要高度的重视,好吧,高度的重视OK,那我现在呢,把这个解决方法给大家提到这里,写到这啊。好,我们把它板书一下好吗?板述一下就是一个思考题。这个思考题呢,他是这样做的。是不是?这做一个思考题。这个思考题,我们给他来一个标题三。没问题吧,好思考什么,思考这个问题对不对,思考这个问题,那么后面我们这个怎么解决呢?啊,解决方法如下。解决方法,录像好的,我给大家进行一个板述。
29:03
具体来说我解决是这样解决的,对不对,首先呢,这里有一个student顶购啊student点购,呃,为了好看干脆这样子。我这块为了让让大家看的比较清晰一点,我整个把这块。包括这个项目的结构,给大家一起放过来好吧,这样大家看的就比较到位了,看首先我们这个项目的结构是这样子的。Factory里面有个model包,那这个文件是哪个文件呢?这个文件就是student这个包。是不是student.go这个对应的文件,我们在解决的时候其实就是用了这个方法。是不这。能看出来吧,好,OK,这是第一部分,我们把它放这里。这个应该这个图截的就比较到位了是吧,包括这个项目的结构以及这段代码,这这这这段程序是属于哪一个文件的,从这个图上就看的一目了然了,当然还有一个。
30:05
还有一个文件就是这个main.go是吧,我怎么去访问的呢?这块也要把它写清楚。好,把这个代码给他记清楚一点。同样这里呢,它是哪一个是这个main.go是不是这个main点构好main.go的它的一个文件代码在这里,那关键代码在哪里呢?关键代码在这。是不是这个地方。是不是就调用了我们点go里面写的一个方法,C的方法,就是student这个结构体指针类型的这么一个方法,所以说你看这个描述起来有点有点费劲啊啊,就16的结构体指针的类型的这个get score这个方法明白。好,我把它呢整理到我们的笔记里面去。好,这些东西都很都很重要啊,等到你把老师讲的这些细节都学完了,我可以负责任的讲,就是后面你去听项目就跟玩似的,真的是这样子,因为构语言的本身项目它本身也不是很复杂哦,它本身结构跟那个Java意义,还有那个大数据不是一个层面上的,呃,所以说他这个呢,呃,做项目的时候还是很轻松,但是你如果这些基础啊,就是尤其是这些原理性的东西没有搞清楚,我可以负责人讲,你后边听起来会非常吃力,你几乎就。
31:26
别人写这个代码,你就搞不懂他是到底是怎么运行的,好吧,这个不是吓唬大家啊,大家一定要在这下点功夫,好,那那这块呢,我们就说关于公,诶干脆我们把它都提到上面去吧。看能不能放在一起啊。能放在一起呢,就放在一起就算了,放在一一个页面。还能说一点儿吧。还能说一点儿。这样就可以了,这个再缩一点。他再缩大一点,这样子。好,放在一个页面,大家看起来比较轻松,好,同学们,那关于工厂模式的这些内容呢,我们就全部讲完了,到此呢,我们这一个就是面向对象的第一个部分,就是上这一部分呢,就全部说到这儿,大家呢,把这个笔记,包括老师布置的作业好好的解决一下,然后再继续往下面继续学,好,一定要把作业练完,再接着往下听,好吧。
我来说两句