00:00
看一下,那么装饰者模式,你要这样去理解好,装饰者模式就像打包一个快递一样,他认为装饰者模式就是一个打,打一个快递,主体是比如说我们这个在淘宝上买了1111个产品叫陶瓷,买了一个陶瓷产品或者买了一件衣服,那么别人怎么给你快递过来呢?先给你打包,不能把这个陶瓷直接扔给你吗?对吧?碎了怎么办呢?我们先来包装一下,比如说诶,我在卖这个陶瓷的时候,我先用报纸或者塑料泡沫给你包裹一下。对吧,也可能用的是纸板,也可能是用木板,这个就是我们的主体,而包装者是谁呢?包装者就是这个。对啊,主体是它包装的是我们这些修饰的东西,哎,这样同学们想,我们可不可以这样理解呢?说我们的主体,我们叫component主主体component,比如说前面我们说的那个drink drink那个饮料就是我们的主体。
01:01
那么由这个主体我们引申出来一个叫con,这个con,这个con是混凝土的意思啊,混凝土那组合成这个component,你可以理解成这个省呢,这个就是我们的单品咖啡。单品咖啡。明白,这是我们的单品咖啡,那么这个,呃,Decorator是什么?就是装饰者,你可以理解成decorator呢,就是我们的各种调料。好,那么这样子呢,就形成一个新的关系,就是我们有一个component,有component呢,这边可以生出它的职位叫concrete component,就是我们的,具体来说就是我们的单品咖啡,那么在这个component和这个concrete component之间呢,可以设计一个缓冲层。那么你也可以不设计。啊,你可以设计一个缓冲层,也可以不设计,那么这个decorator呢,也也一样的decorator呢,它也会继承这个drink,那么这样子他们两者之间都成为了我们component的子类,那因为他们是指类,所以我就可以进行装饰,装饰者是谁呢?我们将来把我们的这一个饮品放到这里面去,我来装饰你。
02:20
啊,这样讲肯定很抽象,就这样讲大家几乎是听不懂的,那么我现在就说一句,说啊,比如我们实在说一下concrete就对应这个图,你们看一下这个图就是具体的主体,比如前面的单品咖啡,而decor呢,我们认为是装饰者。那因为为什么这样说呢?因为我们喝喝咖啡可以不要调料,比如说我就喜欢喝意大利很很这个很纯的,我啥都不要,我就是意大利浓浓咖啡就完了。然后这个调料呢,是可选的。对吧,可选的,因为我们喝咖啡,有些人就不喜欢加豆浆啊或者牛奶,不要说说装饰者呢,他是是附着在上面的,那么这个关系就说完了。
03:02
说完以后呢,同学们,我们这样子啊,来说一下装饰者的含义,所谓装饰者就是动态的,看这个动态的叫新功能附加在对象上,在对象功能扩展方面比继承更加的有弹性啊,比继承更加有弹性,装饰者也充分的体现出开辟原则,那么这里提到将动态,动态的将新功能附加在对象里面,这个OCP原则在后面代码。有体现,请大家注意好,现在呢,看我的设计方案。咱们不啰嗦了啊,看我的方案,同学们看我这里呢,有一个方案,待会我要做笔记了。我们通过装饰的模式整个就变化了,变化成什么样子呢?同学们看这里。首先这是一个drink。这个drink仍然是做成一个抽象的,这个drink就是我们前面讲的component,而这边呢。就是我们的单品咖啡,它可以独立出来,这个呢就是concrete,而decrete这边呢,就是。
04:06
这边的内容decor装饰者,装饰者里面有我们的各个调料。好,大家看被装饰者在哪里呢?在这儿。这个地方就是我们的被装死者。将来我们会把。被装饰的地方放到这里去,好,那么我对这个代码呢,说几点说明啊来同学们,我现在呢把这个给大家做一做几点这个说明,下面呢,说明完了过后我们就来写代码了。好,先把这个图拿过来看一下。我们针对这个图先做一点说明,就这个图。啊,这个图我们做已经说明,那干脆这个说明写到这,我就直接看了啊,我这写了drink。大家看drink这个超类和前面基本一样。就前面也是这样写的,那么short black这个地方,同学们看到的这一块。这块就是单品咖啡设计,跟前面也一样,那么decorator是一个装饰类,包含了一个被装饰的对象,就是这个drink object就是我们我们修饰的,呃,你可以理解成呃,比如像我们的单品咖啡呀,或者什么什么样子的,那么decor这个cost的费用呢?这里面有一个重要的点,就是它要进行叠加计算,即使用到递归。
05:24
为什么?因为我这个装饰者可以装饰,还可继续装饰,这个有点不好理解,那么大家看下一个图,一下就明白了。看这个图我举了一个例子,装饰者模式你可以这样理解,就是将来呢,我们会这样子。这个是大家看这里。哦,我在这儿做点设计说明。啊,我这做做一点说明啊,第一点。第一点大家可以看到这个图,就是这怎么理解这里面这块呢,相当于说是M。Milk,哦,Milk就是这里有一份milk,加加这个long。
06:04
加这个long black。啊,这这是一份,这里有一份这个啊。有一份啊,有一份这个,那么谁修饰了谁呢?相当于是米尔克修饰了non breaking啊装饰了啊milk尔这个牛奶,牛奶这个装饰了。它装饰了我们的一个long。Long black。Long black。就是谁是装饰者呢?尼是装饰者,谁是主体呢?这个long black。好做完了以后呢,我们大家看到巧克力又把它包包裹来的,相当于说什么呢,用用一份巧克力,第二个呢,就是有一份啊,就是使用,使用什么呢?Chocolate。啊,Chocolate又去干什么?又是又去修饰了啊,装饰了吧,又去装饰了这个东西装饰了谁呢?装饰了它。
07:03
好,紧接着大家看外面还有一个巧克力,然后再是什么呢?又使用一份。这样写使用,再使用一份什么呢?使用chocolate我就先写啊,Chocolate装饰了什么呢?它有装饰了这样一个东西,就是这个chocolate。Shock加米加,我们的这个long long black,就好像说它在递归的或者这个成叠的进行这个装饰,就这么简单,那么这面有个最大的问题,就是将来计算成本的时候,怎么成本怎么说,肯定要用到递归,当计算计算这个成本时,就是计算这个cos的时候呢,要递归的计算。要递归,递归的计算好同学们,这个逻辑我们就说完,下面看代码。拜马骑士。这我已经设计出来了,那么代码呢,因为这个代码量啊,它相对比较大,我就而且代码量虽然很大,但是它重点是理解,所以代码呢我就准备好了,过后我们直接给大家看一下它是怎么实现这个东西的,大家看这里啊,同学们看我呢,代码拿过来先。
08:20
啊,先拿过来,然后我把这个代码给大家打开,咱们搂一眼。那么为了好同学们好看,咱们怎么办呢?好同学们,我们要切换到原先讲的这个章节,我们是CHAPTER17对不对?同学们好,同学们改正思路啊,今天我们这个内容量比较大,因为最后一天呢,要把这个东西给他讲完啊,内容力比较大呢,所以大家要把这个注意力高度集中。我为了我为了让他看的清晰,我就直接把这个拿过来看啊,同学们,我就直接放在我们这个位置,大家看懂了。OK。好,同学们看到这段代码,那么我们怎么看呢?首先我们对照刚才讲的这个图来看,哪个图就这个图。
09:10
首先我们看drink写到哪里呢?打开这里,注意听这有一个drink代码,非常的简单,我写了一个抽象类做点注释说明啊说明。那说明什么呢?这个drink是一个饮品,是表示饮品。对不对,它是表示饮品是一个什么呢?是一个抽象类。抽象类,那这个抽象里面有什么东西呢?最主要抽象描述价格这些我可以先设置出来,包括设置它的描述,得到它的描述得到下个,这个我可以封装到这里,但是有一个东西没办法封装,就是cost。因为你饮品是个抽象的,我也不知道你将来是什么饮品,所以说我这里做成一个抽象方法。啊,注意听将什么呢?将计算计算这个成本。
10:03
成本的方法干什么呀,做成一个抽象方法,哎,抽象方法cost这个大家为什么我要做这种抽签论呢?因为我现在不知道怎么算。你这音频到底是单频,是单频的还是组合,我不知道好,所以说我就先将其做成一个抽象的,没有毛病,那紧着下面这几个,我相信同学们都都很好理解,下面这个说白了就是简单继承一下了吗?那我们看一下,我就随便的找一个啊,同学们看,我就找到一个咱们的意大利溶咖啡。好意大利农咖啡,那么意大利浓咖啡过后呢,我们看这边有些代码是不是他找到不到啊,看是为什么。呃,Coffee,它为什么这个地方它报错报错呢?好我们看看是什么原因找一下。这边没有错,是不是考没毛病。
11:01
哪儿去做了?Drink没有毛病呢,我这写的是。啊,我我找错了啊,我我我应该是找这个,我们看看是是找的。我我看看怎么继承这个coffee去了呢,看看。哦,对了,不好意思啊,我是这样子的,不好意思,我要说一下什么样,就是因为我在这多做了一层,我这地方多做了一层,在这地方我为了我为了这有个缓冲层呢,在我这个地方,在我们地方我多多做做了一做了一层缓冲层。我这做了一个缓冲层,我当时讲了嘛,这个component和这个concrete component中间呢,可以做缓冲层,也可以不做,所以说我在这儿呢,做了一个缓冲层就是coffee。Co啊coffee,我做了一个这个coffee的缓冲层,所以说是这样子的,这款缓冲层先打开看这啊,这个地方的问题是这的这个地方的问题啊同学们,那么这个地方做了一个缓冲层在什么呢?在这个drink和谁啊和我们的单品咖啡,我这做了一个缓冲层,那我说一下啊,和这个单品咖啡。
12:23
单品咖啡咖啡啊咖啡我做了,我做了做了一个缓冲层,缓冲层缓冲层,那呃,这为什么我要做一个缓冲层呢?因为。因为从这个,从这个扩展性来说,如果将来这个drink呢,除了有咖啡这种大类之外呢,可能将来我们这个咖啡店我们扩展了,除了有咖啡这种呢,呃,这种产品还有我们比如说我们像中国人比较喜欢传统的那种饮品,对吧?诶我就我就把它分开,大的分开说做了缓冲城,其实如果仅仅针对这一个案例来说,可以不要啊,只是这里是为了扩展,是为了扩展。
13:08
扩展,那么针对该项目,针对当前这个项目可以不要,项目可以不要啊,就是如果只是针对我们这个,你是可以不写的,那么我把这个写进去,说目前这个地方其实意义并不是很大,只是简单的把这个把它分类调了一下而已,其实它仍然是个呃,就是简单的调了一下而已啊,点单调一下而已,那么下面呢,就是我们单品咖啡了,大家看我随便找一个espresso。这个就是我们的单品咖啡。这个是单品咖啡,咖啡那么就是什么呢?在这个设计模式中,在装饰者设计,装饰者设计设计。设啊设计啊,设计模式中是什么位置呢?就是在这个设计模式中,它就是这个康。
14:03
Concrete。唐。刚才这个是concrete。看一下这个单词啊,Concrete是前面咱们写的一个单词,叫混凝土的意思,叫这个concrete。Concre,诶,这个单词怎么老记不住啊,哎呀,Concrete,这个concrete con啊,Concrete conre。就是这个。Concrete。好,就是等于它这个呢,Coffee就相当于是那个缓冲层,这里面我就实实在在的去掉了它的方法,在我这边写了一下,给他设置了一个六块钱啊,当然这个值呢,将来我们可以把它做成一个这个参数传进来啊,我这为了省事,我就直接写到这了,将来同学们呢,可以把这个设计到这里去,那么这边就设计了,其他以此类推,不说了,这个地方是我们的这个long black,就是美式咖啡,这个是我们的short black,还有一个呢,就是我们无音咖啡,写完了那这一大块就够。
15:09
搞完了,就这大块就搞完了,那么decorator,这是关键,我们装饰者模式体现的价值就在这体现出来的,怎么写的呢?大家看这里,打开我们的这个地方装饰者,那么装饰者我是怎么写的呢?这个是关键,Decorator好,同样我把这个先删掉,我重新引入我的B。写完了,那这个就是装饰者。这个啊,这个就是就是我们的decorator啊,把这个DEC call啊装饰者。就是我们的装饰者,那么这个装饰者怎么体现出装饰了呢?大家看,首先它仍然继承这个drink,即这条线是成立的。然后被装饰的对象是在哪里呢?同学们,被装饰的就是它,这个就是被装饰的。
16:01
这个object。Object就是被装饰的对象,就是这个drink。那么我要说的是,这个被装饰的,它可以什么呢?这个object可以是单品咖啡,它可以是单品咖啡,咖啡也可以,也可以是单品咖啡。单品咖啡。咖啡加这个调料的一个组合调料。调料的那个组合好,这就是被装饰的那个对象,那么这个地方构建这个我就不说了,关键是看这个地方我们说计算成本怎么走的。这个地方计算成本使用啊,这里我们实现实现。呃,实现。实现了这个cos的方法。而这个cos方法我们是怎么写的,大家看这首先我们先得到。
17:02
自己的。咖啡,然后后面是递归的调用,因为你这个drink呢。可能里面还有组合,所以说我这里用的是递归的方式。这里使用了递归方式实现。啊,你看这个object定义的cos,因为它将来里面可能还有吗?Drink里面还有,所以不停的往上,因为它是装饰,装饰,不停的装饰,大家看这个组合关系,刚才我们讲的这个这个图,大家应该还有一个关系理解,让他不停的往上面去。递归计算,那么这个地方获取信息时呢,也要递归的,我把这个删掉,这是我留的一点东西,递归的获取信息,这就写完了。那下面呢,我们来看我们的这个,呃,巧克力。包括我们的milk,包括我们的solid,我们看怎么用呢?好,同学们,我把这个先删掉。大家看我这里是怎么玩的啊,这个地方要好好的理解一下chocolate看是怎么来的,看这个图。
18:06
看这图,Chocolate呢,他要继承我们这个decorator。他要继承,那么继承怎么继承的呢?看我继承DEC。然后我要在这个巧克里面放一个,放一个drink,比如说我要放一个drink放进去,然后扩展它就行了,然后这边巧克力呢,我们认为是一份巧克力三块钱。巧克力也是一瓶一个饮品啊,他最终因为decorator,他又继承drink嘛,所以。放到这个体系里面,它其实也是一个drink的脂类,所以这边呢,也可以调用是一份,假如说一份巧克力。巧克力。是巧巧克力多少钱呢啊。巧克力是三块钱。好,其他依此类推了,其他像我们的牛奶一样的道理,牛奶呢,我们也将去不停的往上继承。
19:02
由来是两块钱一份,还有豆浆,豆浆呢是一块五一份,好,这就写完了,写完过后同学们看啊,下面就来看怎么调用了,使用的时候呢,我是这么使用的,大家看代码,我先把这个注销一下,先不要看这个,我们先看一个最简单的啊,先看一个最简无因咖啡,我要引入一下。我要先把这个删掉。删掉过,你们先来看我单点一份。我们我先演示了一个,这是一个咖啡店来了,我先单点一份无因咖啡,大家看这个代码不是不该写这个,要写的话,光这个代码至少都要写半个半个小时。啊,没法没法写代码,只能给你们跑一遍,而且写代码意义也不是很大,你们把这个好好理解一下,这个关系图已经画出来了,你看我这只点了一个单品咖啡单品,如果我点一份单品咖啡,大家看很简单,就是把这个无因咖啡给到这个drink,这是个订单,直接调订单里面cost和得到这个描述,你看因为你这个无因咖啡,我们找一下无因咖啡,它是继承了coffee。
20:09
而coffee呢,他又继承了drink对不对,所以说我们再去调用,这个时候我们当然可以调它这个Co的方法。那么这个cos的方法在哪里呢?点进去一看。哦,是在这儿,但是你后面这个无因咖啡是实现了,你是给了他三块钱。所以说你这运行肯定这边就三块钱就完了,因为你没有装饰的这个感觉在里面,那这个就直接说订单一的价格是三块钱,它的描述是一份,就是这个无银咖啡执行下。抛弃了。同学们注意听。这个地方就打出了它的成本是三块钱。三块钱就就出来了。啊,就是一份,我点了一份这个无银咖啡,三块钱,名字我没啊对无因咖啡在这无因咖啡价格三块写完了。那么现在问题是,当我们有多份咖啡的时候,假如现在我要点一份什么呢?看啊,现在我们的需求是点一份,点一份,这个non break。
21:10
并且并并加加入两份。两份。这个什么呢?巧克力啊,加入两份巧克力,你看我是怎么写的呢?好,同学们看第一句话,这句话大家先看我先。我先来了一份,点了一份这个long f就就写完了,那么因为我是用的装饰这模式,我怎么装饰的呢?非常的简单,我在这个定米的时候。我在定这个M的时候,我直接把这个order放进去就可以了。因为为什么这样放就可以了,我们注意一下这个M尔克是什么,M它是继承了装饰者的,所以说M尔克点进去我们看一下。他装饰的,所以说他继承了这个decorator,那当然他就可以用decorator的相应的方法。
22:01
啊,那怎么做,他也把这个对象传给了这个这个decorator,那decorator拿到过后干什么呢?他把这个decor拿到交给了我们装饰者,看到没有。你看这个就一步一步一步传到这个decor去了。转到decorator去,那传到decorator,当然我就可以统计它的价格了,这是一份这个order,相当于说这个面包裹了一份。Long black,好,这个地方我们就搞定了,我们来打开看一下此时此刻这个价格是什么。来吧,现在我们先布局哦,我这应该是定的三份啊,按你我看我的代码应该是三份,好,你看我现在成本是。大家算一下,这个是五块钱一份。Number 10万这个米是两块钱一份,应该是七块钱,我们执行一下。我们执行一下,同学们可以看到,现在呢,我们打印出来这个结果是七块钱,是一是有一份密尔是两块,还有一份,呃,NUMBER5块加起来好,假如我们现在想干什么呢?不行,我觉得我们还要再来再加一份巧克力。
23:04
如果再加一份巧克力,哦,应该是这样子啊,写错了,加入两份巧克力和一份,应该是这样,是一份。一份这个miracle。密尔和两份巧克力,那么我们再定一个巧克力,就把这个order再放进去,再装饰,那这个时候再一打呢,同学们看,又出现一个新的效果,诶同学们看,现在我们说有份巧克力。啊,三块钱,米有一块钱,Non parker5块钱,这个加起来是十块钱,如果我们还不满意,说老师,我们还要再来一份咖啡。再包裹就行了,好,这样子的好处是将来我们增加一个,大家看,当我们在我们目前这个基础上去增加一个新的饮品时,这个就不需要去动。这些整个类的体系结构了。大家是不是这种感觉,比如说我们现在有一种甜甜的米尔,你看我给他扩展一下啊,比如现在我们还有一种新式的牛奶。
24:07
新式的牛奶,那么我这就省个事儿,我就复制一份这个就行了啊,我们来一份新式的牛奶。来,给他一个名字。来,走啊,六一份有个新的米克来了,就是我们新式的牛奶。那么我给他一个类,我给他一个类,对,然后呢,这个地方一个代码呢,我们神教社直接拿过来用就可以了。哎,那我现在把这个名字改一下。改一下这个不要了,不要,然后这边我们就说这是新式啊,新式的。啊,心式这个。新式的牛奶,然后这个新式牛奶呢,比较贵,比如说是呃,五块四块钱一份,那么这样增加以后,同学们看到我对整个这个体系的结构,我动了吗?我没有动。
25:00
我没有豆,我怎么用呢?非常的简单,比如说诶这个哥们说,哎,来一份吧,我们再整整整一个这个,再再来一份,再这地方再包裹一份六一份新式的牛奶。米尔克说,干什么呢?我在这个基础上,我要加份新吃牛奶,诶,可以可以,你看还是把它返回这个ORDER2。来了,说这个我加了份心思用来,整个就没变化了,你看我动这个东西,我一点都没动。我一点没动呢,然后我一计算整个人家就把你的心思价格也给你算出来了。你看这个代码多爽,就来一份新生牛奶十块钱,总的价格17块钱,多爽。哎,大家要体会它的好处了,当然我如果要去动这上面,比如说我们要单品咖啡再加一份,也是一样的道理,比如说我们再加一份新的一个,比如中国咱们的一种土咖啡,好,这样子加进去也是没问题的,所以你看人下这个设计结构啊,还是非常优秀的一种方案,至少体会到人家一种设计方案的优越知识,你看这就是设计。
26:04
如果你没有这个设计呢,你想将来我们这个需求特别复杂,你怎么搞?我又叫搭加单品,我还要加这个不同的这个这个这个调料,如果你没有这个设计模式,你怎么搞,你会觉得。头都大。这就设计的威力好,同学们关于这一点呢,关于这个整个这个装饰模式的一个讲解,我们就说完了,那么我们来看看。有没有在我们实际开发中,人家用到这种模式呢?诶这个咱们证明一下,你说这个东西好,结果在我们元旦里面没有,在你们Spark里面你们看不到,那说明人家还是有问题的,那么我举一个例子,大家体验一下。好,那么Java里面有一个学IO,你没学过Java IO流里面有一个叫filter input,水这个家伙就是一个装饰轴。这个家伙就是一个装饰者,那么我们来看一下这个原代码啊,各位朋友给你们搂一圈,那么时间时间关系,我们直接就看这个代码了,我们追进去看一下这个东西。
27:08
进到这里面,同学们可以看到这个。这个就是高写写这个Java这个源代码的,这个Java源代面就用到这个东西,你看这个filter。呃,Input他继承了input stream这里面这个东西看volunteer,他这个ER这个家伙就是一个被装饰者,他是装饰者怎么体现出来,看你看我在这里面。这个里边我们继承它,然后非要谁要谁要想去用它就。我我就装饰你就行了。整个这个流程看这个类型的类的一个示意图,看这里看这比如说。我有一个input,你相当于就是那个drink。好像就是那个drink,就是我们的component一样,那么下面的这个filter,文件流,字符串缓冲流better这个地方我们都都可以有,然后干什么呢?如果你们想加入这个过滤的功能。
28:07
过滤的功能怎么办呢?很简单。你就做一件事情,看这里。我去继承你,然后把这个被装饰的,因为你们都是菲的这个子类嘛。而且我也是他的子类嘛,所以说我就可以直接把,比如说你创建那个文件流,我把它扔到这里边去,扔到这里面去呢,这个文件流如果被我一包裹,那么这个文件里也具有了过滤的这种功能。啊,你看他这就实实在在的用到了我们的这一个,呃,装饰者的一个形式,你看这就是comp,这个就是我们对这个就是我们的这个啊,就是我们的装饰者d aorator,而这个呢,就是我们的被装饰者这个流程。好,同学们,关于装饰者呢,老师就讲这些啊,哎,内容看起来很多,但其实最后就是个代码管用,那现在呢,我把装饰者这一块再简单的给他弄一圈,看看他的来龙去脉,把笔记补一下,这样大家印象就更加深刻了,来吧,那刚才老师讲了一个什么呢?讲了一个装饰者模式,体会它的妙用。
29:18
标签我怎么讲装饰者的呢?我先提出了一个需求,引起同学们的思考,这个需求是什么样子的呢?是一个咖啡店的这么一个项目,我的要求是这样写的啊,第一步那个咖啡店它有它有什么。单品稍等一下,有点卡这。好,稍等一下,这有点卡。首先我说了我们这个咖啡店的情况,我们有单品咖啡四种,我们有调料佐料啊,就是三种,然后呢,要求在扩展咖啡种类时良好的扩展性,要求什么呢?用oo来计算不同种类咖啡的费用。
30:01
而且呢,可以单点,可以组合,这是我们提的一个需求,当提完这个需求过后呢,我们马上就来思考了,我们先给了一个很low的设计方法,怎么很low呢?我们就用最原始的,就说你来一个我组合,来一个组合,我就硬生生的给你组合起来。显然这个是很low的,这样呢,会形成会出现一个内爆炸的情况,这是我们的第一个比较差劲的方案,比较它虽然很差,但是呢,它确实也是一个方案,就是我们同学们最喜欢用的嘛,对吧,最简单嘛,简单肯定大家一下就想到了,诶这是我们一个比较差劲的方案。那么这种方案会造成一个什么问题呢?诶,我就分析了一下,我说同学们,哎,这个方案呢,它带来的问题是这样一个问题,什么问题呢?就是我们会出现一个类爆炸的问题。太多了,你加一个组合,加一个组合,你这样子太low了,没法玩,所以说呢,我们就说这个不行啊,虽然不行呢,他但他也不失为一种方案。
31:06
只是你这样写了过后呢,人家可能。十分钟写完代码,你加一个类。我这样设计完了之后,你用这个这个方法,你加一个可能你你你写一个小时代码,而别人呢,可能就是。可能就一分钟写完了,你还在这写,哎,这个怎怎么这么这么麻烦,对吧,因为你的你的设计方案本身就出了问题了。啊,大家看这个我们就描述来这里把这个最最大的问题是这样子的,这种设计方案,它会直接造成雷爆炸,就雷太多了,维护不了了,后面就彻底的完蛋。啊,彻底完了,那出了这个问题过后呢,我们又思考说,诶有没有更好的方案呢?诶我一想咱们想个方案可以这么干。这个方案呢,其实也可以,但是这种方案呢,它有一个最大的问题,就是将来你会直接去修改这个代码。违反了我们OCP的原则。你可以做。
32:02
只是将来这个drink会变得越来越大,也没有层级关系,其实这个方案呢,可行,但是肯定也不上档次,你将来直接修改代码,违反我们OCP的原则,对吧?所以说我们第二个方案是干什么呢?就这样去设计的啊。好,这个方案也可以,对不对也可以,但是呢。那就是违反了我们一些原则。搞这个呢,我们就把它罗列了去,它也算是一个方案。它也是算方案,具体来说,我们这个地方呢,它主要的问题会带来一个维护性的问题,就维护性会差。怎么又卡了呢?好,稍等一下。我动不了。啊,这边维护性差,会同时也违反了对吧,同时违反了OCP的原则,这个是我们尽量避免的。所以说这个方案呢,也不够好啊,也不够好,我把这个图给他拿过来啊。拿过来不管那么多嘛,他也算是个方案,那么于是由这两个问题导致我们要去好好的想怎么解决这种类似的情况,于是我就提出了一个第三种方案,啊,第三种方案是什么呢?就是装饰者模式,那么在讲装饰者模式的时候呢,我先说一下装饰者模式的原理,你可以这样比较一个情况,就说说我们这里有主体。
33:23
那么主体里面呢,咱们要有很多的这个包装,那就来一个先先加加层报纸,再加塑料膜,再加纸板,再加木板,啪啪啪把它包起来,诶这个东西它就很结实了,我们先用纸。报纸把它填充一下,再用泡沫再把它包一下,再用纸板给它再打一个包,最后用木板用木箱子关起来,好,你这个价值1000万的陶瓷,应该即使面对暴力小哥,他也不会被干掉是吧?扔没事儿,我那面好多层了。诶,这就是一个很形象的比较,那么这里面呢,我们就这是形象的生活的案例,我们就把它抽象出来,主体这个呢,就认为是我们的component者。
34:06
Component。哎,那么这个包装呢,就是我们的decorator啊,Decor就是我们的装饰者decorator。那么这样子设计完了过后,我们就提出了一个设计方案,什么方案呢?就是我先抽象出来一层,因为你下面可能有很多指位吗?你这个有陶瓷还有衣服嘛,于是我就抽就出来,Complain啊concrete complain啊,继承它,装饰者也继承它,只有大家都是同样的,都是它的子类式,我们才能进行这个递归的进行一个计算,你不是同一个我们发递归。好,这样关系就形成了,这是前面的一个比较,大家硬看一看也清晰了啊,同学们好,我把这个原理给同学们板述一下。好,我讲第二这边过的时候,大家应该比刚才要。感受要深深刻一些了,对不对,好这个呢,我整理一下四点对不对,好,这是老师讲的四个点,那么来看一下,整理一下,第一个先说一下装饰者它的这么一个比较所主体,哎,这个主体就是我们的。
35:17
这个这个最重要的,然后呢,这有包装。诶,这是包装,然后呢,这地方我们提出了component和这个对吧,然后呢,我们这提出一个component的概念,Component是我们的,应该是第二个。啊康不是我们第二个,诶怎么又又卡了,今天这个怎么机器变这么慢了呢,有点感觉。是是有病毒了吗。不道没道理啊,这个怎么今天感觉很很很卡似的。啊,Component,然后这边component就是它,紧接着我们又说了这个装饰者的概念,好,这个大家去理解一下装饰者是谁对吧?比如前面的单品咖啡decorator又是谁呢?诶也又说了一下,这个decorator就是我们的这一部分代码。
36:02
把它整理一下写到这儿啊。呃,那么当我们把原理说完了以后呢?诶把它粘过来吧,这样是粘到下面去,上面这个先删掉,尽量把它排版好一点。好,装饰者就这样一个关系,那么有了这样一个分析过后呢,同学们,下面呢,我们就来了一个案例,就是具体的说,诶这个案例啊,就是装饰者定义也把它拉过来。这不,装饰者定义就是我们的第三一个对吧,第三一个,然后所装饰者模式的概念是什么,别人问到你呢,你能答的上来。啊,怎么理解这个装式的呢?就是动态的将新的功能附加在对象上,动态两个字很重要,不是说诶你这个要去非要改一下源代码,它比继承更加的有弹性,的确装饰者在这个层面上,他确实继承很很弹性,它这里面其实充分利用了一个什么递归啊,充分利用递归的一个特性。啊,也体现了开辟原则。
37:02
对,然后这个装饰者定义完了过后呢,我们就实实在在的用我们的代码来实现,我们先用装饰者设计模式重新搞了一个设计方案。啊,这个方案呢,就是这样一个方案,大家一看就很清晰了。保持这么一个设计方案。好,我把这个方案也给大家拿过来,对吧?这是我的一个设计方案,具体来说,把这个图放到我们的笔记中。这是这个方案的一个说明,对,大家一看就明白了,那么明白这个道理以后呢,方案设计方案出来过后呢,我们就来了一个代码实现,就具体的说怎么做出来的,哦,这还先写了一个案例,说诶怎么去理解这种装饰。啊,还写了一个案例才走的代码,比如说现在呢,我们要去下一个两份巧克力加一份牛奶的,一个美式咖啡,是怎么做呢?是这样做的。这边是我的一个说明。
38:00
拉过来。好,这个做完了以后,我们就来走了一段代码,就是用装饰者来完成了。这个咖啡的下订单的这个事情写到这来。标题三,那具体说这个代码呢?目录结构我们来看一下是这样子的结构。这是我写的。啊,因为代码量太大。所以说我就直接拿过来给他看了一下,但是呢,应该是看得懂的啊,这边是我们的这一部分,就是my my coffee,这边是我们的装饰者啊,这边是我们装饰者,这边是我们去使用它。哎,就是这么关系就出来了。然后呢,我把它拿到这边来。啊,这边那具体代码呢,这样子我们直接。把刚才咱们写的这个复制。复制一下到哪里去呢?到我们的这个桌面,这个我就不要了,这是以前的那个版本对吧,把它放到我们的笔记中去。
39:00
放到笔记中去,好,这块呢,放到这来了。好,同学们,那关于我们这个装饰者模式就讲到这里。
我来说两句