首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件开发 >

设计方式-装饰模式(Decorator)在jDK中IO系统的应用

2012-11-05 
设计模式-装饰模式(Decorator)在jDK中IO系统的应用该模式在java中比较典型的应用也就是jdk的io系统了?? ?

设计模式-装饰模式(Decorator)在jDK中IO系统的应用

该模式在java中比较典型的应用也就是jdk的io系统了

?? ?装饰模式类图

?? ?设计方式-装饰模式(Decorator)在jDK中IO系统的应用

好吧,其实这类图只对UML熟悉的人才有用,装饰模式有啥用?说白了就是在原来类的功能上,对这些功能做一些增强处理,当然为了增强功能而通过继承也是一种有效的方式,当然对于各种组合比较多的情况下,使用继承可能会有太多的类出现,所以就需要使用装饰模式,当然装饰模式的缺点也是显而易见的,使用上会比较麻烦。

举个例子:

?? FileReader

?? StringReader

?? 我要为这两个类的read功能增加缓存功能,如果使用继承方式,我需要两个子类来完成,也许这两个子类得叫BufferedFileReader和BufferedFileStringReader,如果要增加缓存功能的类有十个,那么子类也就需要十个,但是如果用装饰模式,我只要增加一个装饰类既可满足,BufferedReader类,这个就是jdk1.1的io系统设计。

普通的装饰模式简单示例

view plaincopy to clipboardprint?
  1. //总接口??public?interface?Compoent?{??
  2. ????public?Object?needGirl();??}??
  3. ??//执行类??
  4. public?class?GirlGet?implements?Compoent?{??????public?Object?needGirl()?{??
  5. ????????//?TODO?Auto-generated?method?stub??????????System.out.println("给你个素颜的女优美眉");??
  6. ????????return?null;??????}??
  7. }??//装饰类父类,可有可无??
  8. public?abstract?class??Decorator?implements?Compoent?{??????public?abstract?Object?needGirl();??
  9. }??//装饰类??
  10. public?class?MakeUpDecorator?{??????private?Compoent?c?=?null;??
  11. ????public?MakeUpDecorator(Compoent?_c)?{??????????this.c?=?_c;??
  12. ????}??????public?Object?needGirl()?{??
  13. ????????//?女孩化妆??????????girlMarkUp();??
  14. ????????return?c.needGirl();??????}??
  15. ????public?void?girlMarkUp()?{??????????//?化妆??
  16. ????????System.out.println("素颜的女优不好,化妆下!");??????}??
  17. }??//客户端??
  18. public?class?Client?{??????public?static?void?main(String[]?ben){??
  19. ????????MakeUpDecorator?mud?=?new?MakeUpDecorator(new?GirlGet());??????????mud.needGirl();??
  20. ????}??}??
?

套用io模式的BufferedReader,StringReader,Reader的read功能来做说明:

首先来说明这三个类在上述类图的位置:
Reader:Compoent也是Decorator的基础类

StringReader:ConcreateComponent

BufferedReader:ConcreateDecoratorA

写出简略代码,从jdk1.1中的源码抠出来,去除了很多与该模式无关的代码:

+ expand sourceview plaincopy to clipboardprint?·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150?view plaincopy to clipboardprint?
  1. //BufferedReader??public?class?BufferedReader?extends?Reader{??
  2. ???private?Reader?in?=?null;?????cb?=?new?char[sz];??
  3. ???public?BufferedReader(Reader?reader)[????????in?=?reader;??
  4. ???}?????public?int?read(char?cbuf[],?int?off,?int?len)?throws?IOException??
  5. ???????int?n?=?read1(cbuf,?off,?len);?????????if?(n?<=?0)return?n;??
  6. ???????while?((n?<?len)?&&?in.ready())?{?????????????int?n1?=?read1(cbuf,?off?+?n,?len?-?n);??
  7. ???????????if?(n1?<=?0)break;?????????????n?+=?n1;??
  8. ???????}?????????return?n;??
  9. ???}?????private?int?read1(char[]?cbuf,?int?off,?int?len)?throws?IOException?{??
  10. ???????if?(nextChar?>=?nChars)?{?????????????//当读取的长度超过缓存长度的时候,直接从in里面读取,也就失去了这个装饰类的作用了。??
  11. ???????????if?(len?>=?cb.length?&&?markedChar?<=?UNMARKED?&&?!skipLF)?{?????????????????return?in.read(cbuf,?off,?len);??
  12. ???????????}?????????????//如果读取的下个字符索引超过了当前的缓存长度,也就是说不在缓存中,那么重新加载下一组缓存.??
  13. ???????????fill();?????????}??
  14. ????//当加载缓存后发现,读取的下个字符索引仍旧超过缓存长度,其实就是加载下一组失败,也就是说已经读取完毕了。??????if?(nextChar?>=?nChars)return?-1;??
  15. ????int?n?=?Math.min(len,?nChars?-?nextChar);??????//从缓存中读取字符??
  16. ????System.arraycopy(cb,?nextChar,?cbuf,?off,?n);??????nextChar?+=?n;??
  17. ????return?n;??}??
  18. ????private?void?fill()?throws?IOException?{?????????//创建一个缓存,缓存的长度可设置,为设置是默认的??
  19. ???????//首先从in中获取指定长度的流到缓存中去。加速访问.?????????//核心语句就下面一句??
  20. ???????n?=?in.read(cb,?dst,?cb.length?-?dst);??????}??
  21. }??
?

从上面可以看出,BufferedReader类其实就是将Reader的子类(ConcreateComponent)也就是这里的StingReader的数据放入缓存,然后操作read方法的时候,从缓存中读取,但是实际上的流还是通过StringReader来获取的。也就是说BufferedReader对StringReader类的read功能增加了缓存功能,在事实上,你不使用BufferedReader也可以直接操作StringReader的read功能,只是没有了缓存效果而已。

客户端使用的代码:

String s = "This is the\n\ninternal StringReader buffer.\ndderwe";?

StringReader stringReader = new StringReader(s);?

BufferedReader bufReader = new BufferedReader(stringReader);?

可以看到,客户端使用是比较麻烦的,这就是装饰模式的缺点。

热点排行