装饰设计模式:
当想要对已有的对象进行功能增强时,可以定义一个类,将已有对象传入,基于已有功能,并提供加强功能,其中该新定义的类称为装饰类,装饰类通常通过构造函数接收被装饰对象,并基于被装饰对象的功能,提供更强功能,
装饰模式与继承相比,装饰模式在类很多的时候,要比继承灵活,因为使用了组合方式,避免了继承体系的臃肿.
又因为装饰类的功能是来用增强已有对象,所以也具备与已有对象一样的功能,只不过是另外提供了额外的增强功能而已,所以一般装饰类了被装饰类通常都属于同一个继承体系中.
装饰设计模式特点可以用一句话来概括:"通过构造函数引入,进行功能增强"
下面由一个小例子大概演示一下装饰模式的原理
// class Person { public void chiFan() { //吃饭 System.out.println("吃饭"); } } class SuperPerson { private Person person; public SuperPerson(Person _person) { this.person=_person; } public void superChiFan() { System.out.println("开胃菜"); this.person.chiFan();//原始功能 System.out.println("抽根烟"); } } class PersonDemo { public static void main(String[] args) { Person person=new Person(); SuperPerson sp=new SuperPerson(person); sp.superChiFan(); } } //
类Person中有一个吃饭的方法,只是简单的吃饭
类SuperPerson中通过构造函数引入Person对象,实现对吃饭功能的增强
当然,以上例子只是大概演示而已,并不是一个严格的装饰设计模式,但是已经把设计模式的样子大概做出来了
在JAVA的IO中的包装类就是装饰设计模式的一个具体的使用例子
下面请看一个自定义的MyBufferedReader类
// import java.io.*; class MyBufferedReader { private FileReader reader; public MyBufferedReader(FileReader _reader) { this.reader=_reader; } public String readLine()throws Exception { StringBuilder builder=new StringBuilder(); for(int data=0;(data=reader.read())!=-1;) { char c=(char)data; if(c==' '){continue;} if(c==' ') { return builder.toString(); } else { builder.append(c); } } if(builder.length()>0) { return builder.toString(); } else { return null; } } public void close()throws Exception { this.reader.close(); } } class MyReaderDemo { public static void main(String[] args)throws Exception { MyBufferedReader br=new MyBufferedReader(new FileReader("test.txt")); for(String line="";(line=br.readLine())!=null;) { System.out.println(line); } br.close(); } } //
BufferedReader里面的主要代码也差不多是这样的,只不过这里用的是StringBuilder,而JAVA的IO包里面的BufferedReader用的是数组而已,而且IO包里面的BufferedReader还继承了Reader,
但是并不影响我们对装饰设计模式的理解.当然,你可以直接查看BufferedReader的源代码,
BufferedReader类基于从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
通过接收一个Reader类,基于Reader类每次读取一个字符的方法,通过对这个功能的增强,实现一个每次读取一行的方法readLine();这样就可以每次读取一行字符串了.