大家好,来了解一下设计模式中的装饰器模式,简单来说它可以在不改变原有类功能基础上去动态扩展增加一些额外的功能。 比如说我这里有一个跑绳的一个接口,在接口里面我们可以去实现它的一个子类,比如说我这里实现了一个 superpost, 然后这个生 popopon 里面我们可以去写一个逻辑,比如说他可以用他的一个小脚杆去走他的一个小碎步。 如果说这个时候我要给这个人加一些额外的功能,比如说他现在不只能走路了,他还能骑我们的小单车,或者说我们可以让他开车了, 这个时候我们是在原有基础上加了两个小功能,那他会产生一个问题,原本使用这个类功能的人发现他原来只会走小碎步,现在居然能骑小单车和开车了,那这个额外的功能会影响我, 我只签了一个业务逻辑,所以说我们不能在这里直接加,那我们有什么办法去动态的去扩展呢?所以说我们就可以使用到我们的一个装饰器模式了, 我们在这里可以去实现我们的一个装饰器。简单来说就是将我们的一个 poss 通过构造方法传到我们当前内中去处理他自己的一个业务逻辑,比如说在这里这个类,然后有两个指类,比如说他能骑我们的小单车,拜客以及开车。靠,我们来看下小单车吧。 在这里我们可以通过书跑去调用原本的一个功能,然后再额外给他一个新功能,比如说我们可以去骑自行车了,然后以及他另外的一个卡,在这里也有个卡的一个之类, 然后我们在这里可以给他一个开车的一个功能,然后我们来看一下我们的一个测试类他是怎么用的。在这里 我们首先去溜了一个生泡 pose, 这个能起初只会走路,然后我们可以将我们的一个 pose, 然后通过构造方法传进我们这个拜客里面去, 这个时候就相当于是给我们这个人然后配了一个小单车,配了一个小单车之后发现还不够,然后这个时候我还可以给他配一个小汽车,让他可以去开车,同理也是通过购车方法将我们这个 poss 然后传进来, 然后我们最终再去调用我们这个装方法,然后这个装方法是怎么处理呢?他去去首先调用我们的负类的功能,然后再去处理我们当前类的一个功能,也就是说这个时候他不仅能走路,并且还可以骑小单车,也可以去开小汽车的这里来运气啊,看到他的结果, 可以看到我们的结果不只能走我们的小碎步,也可以去骑自行车,并且可以开车,我不想给他小 小汽车开了,然后可以将我这个贝壳给运行一下,那这个时候他就只能走路和我们去骑小单车的,这样便通过装饰器模式去动态扩展我们的功能,也不影响原有的这个类的功能比较简单,你们 get 到了吗?
粉丝8.4万获赞79.3万

哈喽,今天给大家分享我们设计模式中的装饰模式。首先呢,我定了一个看电影的接口类,提供了一个看电影的方法。 然后我在这边呢定了一个实现类,叫豪华影院。然后呢实现了这样的一个接口。然后我们去实现了这样的一个方法在豪华影院看电影。那正常的一个业务逻辑,我们可以直接去做一个测试。用这样的一个测试类, 那这边显示就是在豪华医院看电影。那如果说啊,我不仅仅想要在豪华医院看电影,我还想要在豪华医院吃零食,那该怎么办呢?当然我们可以直接把代码写到这, 但如果说我们直接把这个代码写在这呢,那就对原来的一个业务逻辑呢造成了一个侵入。那这个时候呢,我们就可以用到我们的一个装饰模式了。比如说我在这边定了一个叫零食的装饰类, 零食的装饰类呢,他同样实现了我们看电影的一个接口。然后我把这个接口呢注入进来,提供了一个构造方法,然后我们实现这个接口的一个方法,然后再去调用 iwatchfield 的一个卧室方法。比如说我们可以这样来测试一下,那我在这边呢溜了一个零食装饰类的一个对象, 然后呢,我把啊豪华电影院的这样的一个对象呢给大家传入进去,对他进行了一个装饰。然后呢,我们再调用装饰类的一个卧室方法,我们去做一个测试。好,这边呢就不仅仅是在豪华电影院看电影了,而且我还带了很多的零食,对吧?当然我还可以在这个装饰类的技术上呢,再对他进行一个装饰。 比如说呢,我不仅想带着零食去看电影,我还想要带一个女朋友去看电影。那我们呢可以定一个女朋友的一个装饰类,女朋友的装饰类呢,我们可以让它继承我们零食的装饰类。然后呢提供了 一个构造方法,然后我们再重写了这样的一个卧室方法。然后在这边呢写上我们的一个装饰的内容叫带着女朋友看电影, 然后再调用我们 super 的一个卧室方法。我在这边呢溜了一个女朋友的一个装饰类,然后呢,我把零食的装饰类呢给他传进去,然后呢我调用了女朋友装饰类的一个卧室方法。我们来看这样的一个结果。 那这边的结果呢就是带着女朋友带着零食带去看电影了。好,那这样呢就是我们的一个装饰模式。今天的分享呢就到这。

各位 java 程序员看过来啊,我现在呢有这么一个需求,这儿呢有一个 user service 实现类,然后呢实现了这个 user service 接口啊,这个接口里面呢 只有一个查询用户的方法,叫 select user, 听,现在我实现了这个 select user 方法啊,去执行查询,读 snack。 那 么现在我的需求是这样的, 我需要在后面加一个缓存的功能,我要把 java 用户啊给我缓存起来,现在我要新加一个这么个功能,那我们平常做法怎么实现呢? 我们一般就直在后边,在这后边携带吗?对吧?实现我们的缓存功能,然后过几天呢,我有一个新需求,我我我需要呢,把这个查询的时间你给我统计出来,就执行这个查询功能,到底耗费了多长时间,对吧?那我们很多人又会怎么做呢? 在这前面把这个当前时间给打印出来,然后呢 在两个时间相结,就继承说他这个执行时间,对吧?那往后我这个需求还在不断的变更,增加很多新功能,你就需要不断的来 修改这个类啊,这个呢就违反了我们的开闭原则啊,你需要修,不断修个燃料弹吧,非常不灵活啊,也很容易出错。那我们 该怎么去解决这个问题呢?这个时候呢,我们就可以用一种设计模式叫做装饰器模式来实现这个我们的需求啊,你就不需要修改然而代吗?增加一些装饰之类,就可以来实现我们的这个需求了啊。好,我们 先来创建一个缓存装饰器类啊,那做 user catch decorator。 然后呢同样我们这个装饰器类呢,实现我们的这个 user service 接口啊,实现我们的方,看方法再对本儿我们又把又包含一个 user service 进来, 然后呢复制呢?通过我们构造器去复制啊,然后呢这个时候我们就可以调用我们这个 当前已有的 user service 的 这个 select user 方法啊,这个时候呢,我们就可以在后边呢来实践我们的缓存操作了,咋着读 catch, 这里面就是真正的缓存操作啊,我就打一句话,也就是说我们先把先利用原来的这个查询用户的方法,对吧?这个程序把数据查出来,然后呢我们再执行这个 缓存操作,这个时候呢,你用这个装饰器类去,就用这个 slide user 方法,对吧?它就实现了这个缓存功能啊,那我们怎么使用啊?先创建一个 user service, 然后呢再创建一个缓存装饰器类啊,我们要用这个装饰器类 来来实现我们的这个 get, 我 们的古方法啊, 创建我们这个缓存装置对象,然后呢把这个 user service 对 象啊传进来,这就是我们原生的这个对象,对吧?原生的这个 service 时间那个对象传进来,这个时候呢,我们调用这个 缓存器对象的三个应用方法,它呢就会把我们的缓存功能啊得加上啊,我来运写一下, 看到了吗?它就第一步是查神数据,第二个呢是缓存数据,这样了,我没有修改我源源机构 机构代码,对吧?这是原生的代码,我没有修改它,我只是加了一个装饰器类 就实现了这个缓存数据的功能啊,那假如说我现在又来了一个需求,需要统计它的执行时间,那我们怎么做呢?我们只需要再新建一个统计执行时间的一个装饰器类就可以了。怎么做啊?矩阵锁, can't time dick。 瑞特啊,实现我们的 user service 接口,实现这个方法, 一样的啊,包含由 user service 进来,通过构造方法附上值。 然后呢,先调用原来的这个 select 方法,然后呢,我们要停机他的这个执行时间呢?怎么做呀?先在前面加一个这个,对吧?把当前时间打出来,在执行结束以后再把当前时间打出来, 两个时间相减,就是我们的这个查询这个耗时时间啊,那我们怎么使用啊? 很简单啊,那我只需要在之前这个基础上,我的缓存需求还是需要的哈。在之前的缓存基础上再加一个吞机失恋这个装置器啊, 这个是我上的这个调样就可以去掉,我们要用这个,这应该叫 control cap decorator 啊,我们要创建一个 control time decorator, 统一时间的装饰器类,然后呢把我们这个缓存装饰器类再给它穿进来, 这个时候我们那个缓存功能他就还保留着。你在缓存的功能上又加了一个统计时执行时间的功能,这个时候我们调用统计时间装置去对象的这个查询方法,那么了他就会再增加一个统计执行时间的一个功能。 看完了吧,查询数据,缓存数据查询时间,因为我这儿查询时间非常短啊,所以它当然是个零,好妙,对吧?这样了,我们也没有是个 ram, 只增压这个统计执行时间,这个功能是不是非常灵活? 你只需要新增装饰器就可以了,它可以层层叠加,对吧?这是我最原始的,然后呢?我整一个缓存装饰器,它就拥有了缓存功能。那么我再整一个 统计执行实验的一个这个装湿器,他就又用又用了这个统计实验这个功能你可以层层添加,你需要那个装湿器,你就用那个装湿机,非常的灵活,这个就是我们的装湿器模式。

我们来一起学习结构型模式中的装饰器模式,这是装饰器模式在所有模式中的位置。装饰器模式 decorator patter 允许像一个现有的对象添加新的功能, 同时又不改变其结构。这种类型的设计模式属于结构型模式,他是作为现有的类的一个包装。装饰器模式通过将对象包装在装饰器类中,以便动态的修改其行为。这种模式创建了一个装饰类。 下面介绍一下装饰器模式一、图动态的给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。主要解决一般的我们为了扩展一个类,经常使用继承方式实现。由于继承为类引入静态特征, 并且随着扩展功能的增多,子类会很膨胀,何时使用?在不想增加很多子类的情况下,扩展类如何解决?将具体功能职责划分,同时继承装饰者模式关键代码 一, component 类充当抽象角色,不应该具体实现。二、修饰类引用汉继承 component 类,具体扩展类重写副类。方法应用实力,一、 孙悟空有七十二变,当他变成妙语后,他的根本还是一只猴子,但是他又有了妙语的功能。二, 不论一幅画有没有画框,都可以挂在墙上,但是通常都是有画框的,并且实际上是画框被挂在墙上,在挂在墙上之前,画可以被蒙上玻璃装到框子里,这时画 玻璃焊,画框形成了一个物体。优点,装饰类焊被装饰类可以独立发展,不会相互吻合。装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。缺点,多层装饰比较复杂。使用场景, 一,扩展一个类的功能。二,动态增加功能,动态撤销注意事项可代替。继承装饰器模式有四个关键角色,我们来分别介绍这几个角色的作用。抽象组件 component 定义了原始对象,看装饰器对象的公共接口或抽象类可以是具体组件类的副类或接口。具体组件 concrete component 是被装饰的原始对象,他定义了需要添加新功能的对 像。抽象装饰器 decorator 继承字抽象组件,它包含了一个抽象组件对象,并定义了与抽象组件相同的接口,同时可以通过组合方式持有其他装饰器对象。具体装饰器 concrete decorator 实现了抽象装饰器的接口,负责向抽象组件添加新的功能。具体装饰器通常会在调用原始对象的方法之前或之后执行自己的操作。装饰器模式通过千套包装多个装饰器对象, 可以实现多层次的功能增强。每个具体装饰器类都可以选择性的增加新的功能,同时保持对象接口的一致性。继续来看 u m l 图,讲解一下实现过程。我们将创建一个 cp 接口 看实现了 ship 接口的实体类,然后我们创建一个实现了 ship 接口的抽象装饰类 ship decorator, 并把 shape 对象作为他的实力变量。 red shape decorator 是实现了 shape decorator 的实体类 decorator pattern demo 类使用 red shape decorator 来装饰 shape 对象。来看一下例子,共有五个步骤, 小彩蛋将优雅进行到底。女孩子家家的就应该端庄优雅,你看你成什么样?

聊聊设计模式中的装饰器模式,这里用煎饼的例子去聊这个设计模式。先定义一个煎饼接口,该接口有煎饼描述和价格两个方法。再定义一个普通煎饼类,该类实现了煎饼接口,并重写了接口的两个方法,说明它是一个普通煎饼,并且价格是八元。然后定义一个抽象煎饼类,该类实现了煎饼接口,有一个煎饼接口属性, 加一个构造方法,并重写煎饼接口的方法,在方法内部调用煎饼接口的方法。接着定义一个加鸡蛋煎饼类,该类继承抽象煎饼类,有个构造方法,重写了煎饼描述和价格方法。方法内部调用副类的方法,并添加了自身逻辑,比如价格在原基础上加了一元。跟鸡蛋煎饼类逻辑一样, 这里还有个火腿肠煎饼类,它的价格在原基础类上加了两元。接着看看如何使用。先创建一个普通煎饼对象,输出描述和价格,再创建一个夹蛋煎饼,并将普通煎饼传给他,也输出描述和价格。最后创建一 个加火腿肠煎饼,将加蛋煎饼传给他,并输出描述和价格。运行一下看效果。可以看到,普通煎饼价格是八元,加鸡蛋后煎饼价格变成了九元,再加个火腿肠后价格变成了十一元。我们在不修改原煎饼代码的情况下, 动态的像原对象添加了新的功能,这就是装饰器模式。看下概念,装饰器模式是一种结构型设计模式,他允许你在不修改现有对象代码的情况下,动态的像对象添加新的行为或功能。主要角色有以下几个,分别是抽象组建,他定义了要被装饰的对象的基本行为。 本例中的煎饼接口就是抽象组件具体组件,它是实现了抽象组件接口的具体对象。本例中的普通煎饼就属于该角色。抽象装饰器,它是一个抽象类或接口, 它继承了或实现了抽象组件,并包含一个对抽象组件的引用。本例中的抽象煎饼类就属于该角色最后一个角色。具体装饰器,它是实现了抽象装饰器接口的具体类,包装了具体 组建,并可以添加额外的行为或状态。本栗中的鸡蛋煎饼类和火腿肠煎饼类就属于该角色。它的工作原理是通过嵌套多个装饰器来逐渐扩展一个对象的功能。每个装饰器都可以在不影响其他装饰器的情况下增加新的功能。优点是灵活性高、可组合性强以及符合开辟原则, 在不修改现有代码的情况下扩展功能。好了,本期视频就到这里,欢迎关注、点赞、评论、收藏,我们下期再见!


我们来学习一下 java 文件操作基础,用装饰器模式实现 java c java 系列化。在之前的小节当中,我们已经把 java 从文本当中提取出来,那么接下来要做的事就是把 excel java 进行压缩。 为什么要说呢?因为原始文件可能会很大,因为莎士比亚的十四行诗全集有一百五十四首。如果我们要储存传输压缩,可以节省空间。再提供了内置的 z z 压缩工具,我们不需要自己写压缩,算了吧,只需要调用 api 即可。我们来看一下压缩的思路, 我们希望把一个 send 的 所有行写入一个压缩后的二阶字文件。我们可以用 z z 外部 stream 该类来帮我们完成压缩。 首先是创建一个比特 ray output stream, 用来存放最终压缩后的二人制文件。然后使用 j byte output stream 来包装的实现压缩功能。 然后再调用 print winter, 方便主行写入字幕串,因为它的 print 方法非常适合写文本。最后返回一个 y 的 速度就是压缩后的字节速度,可以保存文件或传输给其他人。那我们来试一下, 我们来看一下该方法。这里的 battery output 就 相当于一个内存文件,所有压缩数据最终都要存在这里。然后通过 zibib output 把数据写入时,会自动地进行一个压缩,然后我们写一个慢方法。 我们运行一下这个方法,可以看到它在相貌目录下生成了一个 z c 文件,然后我们将它打开, 然后我们将它进行压缩解压, 然后打开解压后的文件,可以看到我们刚才写入的内容。好,这一小集就是通过 library output stream 字节流写入到 cdb 里, output stream 加错流当中,然后我们可以通过解压啊将文件给独立出来。好,这是字节内容。

ok, 今天我们继续零基础学习设计模式,今天我们主要讲的就是装饰者模式啊,装饰者模式, 嗯,我们看一下文档,装饰者模式我们对他的一个定义就是在不改变目标结构的情况下,动态的给对象增加功能啊,这句话其实很好理解的,相对于其他的一些设计模式好。 动态的给对象增加功能就是我们调用目标方法的时候啊,我们需要对这个目标方法进行一个装饰,嗯,也就是什么意思呢?就是在他的 这些目标的时候,方法之后不仅是调用他的一个方法,而且在他还可以会去做一些其他的操作啊,主要是对他的一个,嗯,对象进行一个增强啊,增强的一个功能啊,好, ok, 但是这个增强的功能是跟他的一个业务相关的,跟业务相关的进行一个装饰的作用,装饰的作用啊,然后我们 生活中有哪些?嗯,都是有这些装饰模式的一个例子呢?好,例如像那个房子的装修啊,房子装修本来就一个毛坯房也是可以的,对不对?嗯,有几张床,嗯,还有装上其他的一些什么家具都是可以的,然后同城店加那个装上水,对不对? 好,然后呢你需要再来进行装修,装修你就是,嗯,也贴那个瓷砖啊,对吧?然后呢刷一些乳胶漆啊,对吧?再来进行一个装修,给他美化,是不是?这也就相当于是我们的一个装修模式啊,装饰者模式啊, 啊。然后还有一个相片,将相框加相框,对不对?然后相片本来我们可以单独使用,但是我加上一个相框也还是相片,是不是?他不管怎么样他最终还是不改变他原有的一个属性,就是我这个。嗯,本质上是,是一个什么样的东西?房子再怎么装修你还是一个房子像 片,再怎么加相框,加什么一些装饰的话,你还是一个相片,所以说的话他的主要螺主要功能是不变的啊,只是给他做了一些修饰的一个作用。好, 这个大概的一个装饰者模式的话,我,呃,一个解释大概就到这里了。好,我们再看一下我们。嗯,设计模式中对这个装饰者模式他定了哪些的?一个基本组建对不对?好,基本组建包括四个,首先就是一个抽象构建,抽象构建的意思,嗯,就是 以定一个抽象接口,以接收一个规范,接收一个附加责任的一个对象。啊。啊,这个大概这个奖呢比较抽象。 嗯,他本身就很抽象。就是然后呢?还有具体构建啊,具体构建就是对抽象构建的一个实力化啊,一个实力化,具体的一个实现啊,一个实现。这个前面这样理解,然后抽象装饰 就是我这个装饰者啊,也是一个抽象的,因为他有很多装饰者吗?所以他会在上层抽一个抽象出一个装饰者的,一个一个对一个类出来啊,然后后面一个具体装饰,具体装饰和上面的一个具体构建是一样的,具体装饰是对抽象装饰的一个实现啊,一个实现。好, ok, ok, 好,然后我们看一下类图啊,因为陈欣然的话看类图最容易。嗯,理解了啊。好,我们给他放大一下看一下啊,放大一下看一下。然后首先我们刚才说了,我们有一个抽香的一个构建,对不对?这是抽香咱们抽香的构建, 然后这里一个实现的构建,一个实现具体的构建,这个就是实现他的具体的一个方法,我们到时候去雕兄的话也是去使用这个具体的一个方法啊。啊,然后呢?有个装饰者,装饰者的话怎么去做呢?装饰者也是去,嗯,继承了这个实现的这个借口,对不对? 实现的借口跟构建一样,实现的这个借口,只不过他在实现的一个,他是他也是抽象的,他还是抽象的,只不过他在抽象的过程中他去包了一个这样的一个构建进去啊,这个构建的话就是他, 嗯,后面用到的一个具体构建到了构建进去,然后呢他这里面传了构造器,构造器的话就是把这个构建啊传进去啊,同样呢他也去试,嗯,定了这样一个方法啊,实现这个方法。好,然后呢咱们这个方法的话就直接是去调用咱们的一个具体构建的一个方法了。 好,这里面是这样的。好,然后我们再看一下,因为我们有一个抽象的购,抽象的是那个装饰者,是不是抽象的一个装饰者?抽象装饰者。然后呢他在副副级上面已经做了这个,嗯,通过聚合的一个模式啊,把这个看破凳子 组建给他聚合进来了。然后呢我们需要对这个装饰者模式进行一个实践啊,这个可以有多个实践,我只是写了两个啊。嗯,做最他的一个。 呃,继承他,继承他,然后继承他的过程中的话,我们也提供了个的话,这个是必须要提供的啊,你不提供的话,你这个是会爆错的,然后呢,我们也提供了一个没错的 a, 对吧?这个方法,然后还有一个这个没错的 a 方法。好,然后呢? 咱们在这里面啊,其实这里面还少了一个方法啊,其实这里面对在我们用的那个那个逼的方法,是不是, 然后呢?这里面这里面有一个提供了一个方法 b, 然后怎么做去做呢?方法 b 怎怎么去做呢?然后就是在我调用方法 a 的时候,我先调用了一个 a 的方式,在这个功能进行一个增强了,对不对?进行装饰了,对不对?进行装饰?这有可能大家对这个模式跟 那个代理模式啊有点分不清,是不是啊?其实他们俩的一个目标是不是一样的?嗯,可以说是这个装热模式是那个代理模式的一个特殊的一个竞赛代理模式啊,好, 带领模式,他的区别后,后面,我后面,我会在后面跟大家统一讲的。好, ok, 大概是他的一个类图,大家相信应该也能看清楚了。好,然后呢?我们今天的主要轮任务是我们把大码进行实现啊,大码进行实现。好,我们首先说一下,我们每个上面不是说了四个组建吗?哦,对吧?我们现在的话大概啊是五个组建啊,是五个组建,嗯,五个类啊, 我们给大家看一下啊,大家看一下,首先我们定义了一个抽象的一个接口啊,接口是一个勾肩啊,就是我们的一个勾肩扛把弹的勾肩,然后里面有一次给我的方法,对不对?好,然后呢咱们这里 你们看一下这里面还,然后再定了一个具体的一个时间的一个构建啊,这里面就是直接放着开始执行原始操作,是不是好?执行他的一些操作?然后这里面的话有一个啊,对了,忘记跟大家装饰者模式的话,也是一个构造模式啊,也是一个构造构造构,结构型模式啊,结构型模式啊。好, 然后我们继续看一下啊,看一下,然后我们这里面定了具体构建之后,我们再又去定一个抽象的一个装饰者模式,去继承这个实现这个构建的一个借口啊,然后这里面会据通过聚合的方式引入了一个这个看不到的时间跟露腿跟那个类图是一致的啊。好, 然后又定了一个,嗯,具体的一个各自一个装饰者,装饰者,好,工装者里面的话就直接去,嗯,去,嗯,在执行目标方法的时候, 他去首先去调用了目标方法,对不对?但是在调用目标目标方法之前对他做了一些增强处理,增强处理好,然后呢?最后就是个测试类好,然后我们直接看下运行一下代码啊,看一下效果。好的,我们看一下这个慢放码啊, 大家可以看一下这个运行结果啊,首先的话他是对方法进行一个装饰处理,是不是?然后执行目标的一个方法,对不对?好, 好,这里面是直接是通过这个装修者模式,我们去用了这个,呃,在调用的目标方法,对不对?好,我,然后我们现在做这样一个处理啊,我们直接去调用这个目标构建啊,我们假如啊,假如我们这里面我们不去执行这个方法,不去用他的, 我们反而是直接用他的一个原始的,这看不到点 sq, 对不对?我们用这个方式看下他是一个什么样的效果啊? ok, 可以看到他只执行了开始执行原始操作,是不是?所以呢?咱们通过这个装饰者模式啊,在这个,呃,目标的一个构建啊,做了一个装饰啊,装饰的作用,好,这就是。嗯,一个装饰者模式。嗯,今天的内容就分享到里,后面的话我们继续讲其他的一个设计模式。好,谢谢大家。