天命吃鸡还是落地成盒 学学装饰模式先

java零基础入门-高级特性篇(十三) IO 流 3

本章介绍另一个流派-字符流。其实如果上一章字节流已经掌握的话,字符流学起来会更加简单。先来看看字符流的结构,他与字节流的结构稍有不同。


主要类

字节流中主要的类有4个,而字符流中有6个,简单介绍一下这6个类。输入流中FileReader是核心,虽然是核心类,但是其实它本身没有什么功能,类中只有构造器,它继承InputSteamReader类,主要功能来自于继承的InputSteamReader类。而BufferedReader是将FileReader包装后,具有缓冲功能的字符输入流,文件较大请使用带缓冲功能的流。

 FileReader

字符流

FileReader的例子和上一章字节流的写法十分相似,也是首先根据文件路径创建File对象,然后设置一个字符数组,最后循环输出读入的字符。用法难度不大,这里主要来看看FileReader里面到底在干什么。

FileReader

FileReader里面只有3个构造器,而构造器里面创建了字节流然后作为参数传给了父类的构造器。为什么字符流里面用的是字节流?往下看,父类InputSteamReader的构造器里面有一个关键的类-StreamDecoder,这个类的作用就是对字节流进行编码和解码。这样一来,就能弄清楚FileReader和InputSteamReader到底是做什么用的了。

FileReader的作用,其实是表示“我是字符流家族的”,然而它背地里偷偷跟字节流家族搭上线,它的存在只是保证了字符流家族的完整性。

InputSteamReader的作用,帮助FileReader在背地里将字节流进行编码转换,让字符流看上去是在直接处理字符,所以他还有个名字叫做“转换流”。

虽然字节流和字符流都可以处理中文,但是在处理需要编码的文字的时候还是建议使用字符流,这样会减少发生错误的几率。

FileWriter

写入文件

字符输出流看上去要简单很多,首先根据路径参数创建一个文件,然后将内容写入到创建的文件中。但是这里要注意一个地方,就是FileWriter的flush方法。这个方法比较重要,因为如果在最后不调用这个方法的话,文字是不会被写人到文件的。原因就是FileWriter有缓冲区,flush方法就是将缓冲区中的内容清空,把文字写入到文件。这里肯定有同学会问了,这个FileWriter名字上没有Buffered这个标识啊,为啥会有缓冲区?这里要说明一个概念,FileWriter是有默认的缓冲区大小的,而带有Buffered的缓冲输出流的缓冲区是可以配置大小的。

字符缓冲流

缓冲流

和字节流一样,更高级的缓冲流只需要对字符流进行一层包装即可,然后流就具有缓冲功能了,并且是可以设置缓冲区大小的缓冲功能。上节说过,流是需要关闭的,在关闭流的过程中,会自动检查缓冲区的内容是否被清空,如果没有清空缓冲区就关闭流,程序会自动调用flush方法清空缓冲区。所以,一般只要记得关闭流就可以了,不需要特意去清空缓冲区。

装饰模式

前面讲过工厂模式,这里再来讲一个装饰模式,因为缓冲流这种设计,就是最好的装饰模式实现。装饰模式是啥?我们先来吃把鸡就应该懂了。最近吃鸡游戏很火,要想吃鸡,你需要装备性能好,配置高的武器才行,比如我比较喜欢用的是M416这把武器。这把武器的配件非常多,虽然搜起来比较困难,但是一旦全部搜齐了,交战起来火力那是可以秀敌人一脸的。

没有配件的M416这把枪就是下面的样子。如果没有配件,用起来是非常困难的,首先没有瞄准镜,瞄准敌人很困难,其次没有握把和枪头,开火后难以控制准星,所以我们需要尽快搜到配件安装到枪上,才能提高我们的作战能力。

M416

来看看如何设计代码,首先游戏里面肯定不止这一种枪,除了步枪还有手枪,狙击枪等等,所以老规矩,将枪作为父类提出来,作为抽象类,可以实现枪的公用方法,也可以只要抽象方法,不同的枪都来继承它就行了。M416继承了枪这个类以后,只需要实现枪这个类定义的抽象方法即可。

M416的代码

这里只实现了一个M416,当然各位也可以实现其他的枪,比如SCAR,98k等等。只需要继承Gun这个父类即可。但是这里要说明的不是实现各种枪,而是要实现枪的配件,下面看看一把有配件的M416长什么样。

配件

现在要开始设计带有配件的M416的代码了。那么问题就来了,配件不是固定的,我们可能刚落地就搜到所有配件,也有可能直到游戏结束都只能搜到一个配件,所以我们设计的带有配件的M416不是固定的,也就是说我们有很多种可能会出现的M416形态。

可能形态

看到这么多种可能,有的同学可能掐指一算,嗯~1+2+3=6个类,撸起袖子开始顺着写6个类。我想说,其实我这里只是简化了配件数量,其实M416的配件还有弹夹和枪托,并且每个部位的配件可能不止一种,比如弹夹还可以分为扩容弹夹和快速弹夹,真要一个个写下来,可能几十个类都写不完。那么该怎么办?让他们自由组合就可以了,好了,装饰模式登场了。

装饰模式可以动态的给一个对象加上更多的责任(功能),在不需要创造更多的子类的情况下,将对象的功能进行扩展。来看看如何使用装饰模式解决上面这个问题。

首先创建一个抽象装饰类,这个类的作用就是动态的传入对象,这个对象只要是Gun或者Gun的子类都可以,简单的说,只要传入一把枪就行,然后用具体装饰类对这个抽象装饰类进行“装饰”,加上各种功能即可。

抽象装饰和具体装饰

抽象装饰类,用于维护一个对象,这个对象可以是任何一个M416,没有配件或者有配件都可以,然后在具体的装饰类中,可以继续对这个对象进行功能的添加,这样就可以在M416的基础上,配置各种配件,而不需要为特定的形态创建新的类。

装配M416

首先创建一个无配件的M416,再创建3个带配件的M416,最后创建一个有所有配件的M416。这里最重要的就是好好理解抽象装饰类的作用和具体装饰类的作用,正因为有了这两个重要的部件,才能灵活的对各种功能进行组装。

理解了上面这个例子,再来对比一下这个例子和IO流中的设计,来看看IO流中如何使用装饰模式。

对比

左边的结构就是上例的结构,各位应该已经明白了。再来看右图,有没有发现结构几乎一样?其实不止结构一样,连功能都几乎没有区别,前面章节说过InputStream是所有字节输入流的抽象基类,其实他扮演的角色和Gun一样,他就是为了构建各种字节输入流而存在。FileInputStream就像没有配件的M416一样,他只有最简单的功能,如果需要额外的功能,需要创建抽象装饰类,然后创建带有新功能的具体装饰类。来看看代码上的对比。

对比

缓冲流的用法就是将普通流作为参数传递给缓冲流构造器,这与M416加配件的过程一样。都是把没有附加功能的类,包装成带有各种新功能的“高级类”,而在IO流中,当然就是“高级流”了。流的家族很大,这里只介绍了最常用的缓冲流BufferedInputStream,其实还有很多其他带有功能的高级流,比如上图中LineNumberInputStream也是一种带有功能的高级流,它的功能是获取当前输入流的行数和设置行数,这些都是具体的装饰类。

以上就是字节输入流的装饰模式展示,其他字节输出流,字符的输入输出流也都是装饰模式,结构上大同小异。这也是为什么IO流家族体系庞大的原因之一。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 一、基础知识:1、JVM、JRE和JDK的区别:JVM(Java Virtual Machine):java虚拟机...
    杀小贼阅读 2,362评论 0 4
  • tags:io categories:总结 date: 2017-03-28 22:49:50 不仅仅在JAVA领...
    行径行阅读 2,166评论 0 3
  • 21.01_字符流FileReader 1.字符流是什么字符流是可以直接读写字符的IO流字符流读取字符, 就要先读...
    苦笑男神阅读 572评论 0 3
  • 酸甜苦辣咸,人生百味。作者真的把我写饿了。我每回吃完饭,或是快到下课的时候,就要看这本书。就会感叹,学校的饭和外面...
    天作棋盘星阅读 305评论 0 3
  • 种菜日记4今早8点40出门,给车子加满油,悠哉悠哉朝学校驶去。 校园菜地静谧得很,偶尔有一两个食堂工人在大道上走过...
    木铎的召唤阅读 123评论 0 1