黑马软件工程师_<<装饰设计模式>>
--------------------ASP.Net+Android+IOS开发、.Net培训、期待与您交流! --------------------
1. 装饰设计模式
1. 概述
装饰设计模式是对已有类的对象进行封装,然后使其具有更强大的功能,当定义好的类功能不够完善的时候,我们不希望是修改源代码,那么我们就可以定义好一个类,把其对象封装到里面,然后对其功能进行扩展。
一般设计的模式:
当你想要对已有的独享尽心功能增强时,可以定义类,将已有对象传入,基于已有的功能,并提供增强功能,那么自定义的该类称为装饰类。
装饰类通常会通过构造方法接收被装饰的对象,并基于被装饰的对象的功能,提供更强的功能。
2. 应用实例
当我们操作IO流的时候,在读取或者是写入的时候,使用的是FileWriter和FileReader,由于效率不高,我们采用了缓冲技术,BufferedWriter和BufferedReader,这样我们就提高了效率,实际上这里就是使用了缓冲技术,装饰设计模式,把Writer和Reader封装到缓冲类中,对其功能增强了,增强了跨平台的newLine方法和读 更方便的readLine方法。都是基于现有类的方法进行扩展的。
下面我们就模拟一下这个实例:
import java.io.FileReader; import java.io.IOException; import java.io.Reader; public class MyBufferedReader extends Reader { private Reader r= null; publicMyBufferedReader(Reader fr) { super(); this.r =fr; } /* 模拟readLine的话,其实里面封装了一个数组,我们为了方便,就封装StringBuilder对象,这样操作方便*/ public StringreadLine() throws IOException { StringBuildersb = new StringBuilder(); int ch =-1; while ((ch= r.read()) != -1) { //System.out.print(ch+","); 从输入的个数判断出 if(ch == '\r')// 当文件中就存在\r,那此时是否存入StringBuilder中呢,开始我认为是不会存入的,但是结果输出了,难道是读取的时候例如:\r,把\ //和 r分开读取了,这样理解的话,就通顺了 continue; if(ch == '\n')// 这里和\r的疑问和理解一样 returnsb.toString(); else sb.append((char)ch); } if(sb.length() != 0)// 这里解决了,最后一样没有回车,防止最后一行不被输出 returnsb.toString(); returnnull; } public voidclose() throws IOException { if (r !=null) { r.close(); } } @Override public intread(char[] cbuf, int off, int len) throws IOException { returnr.read(cbuf, off, len); } } import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; public class ClassDemo { public static void main(String[] args) { MyBufferedReader br = null;// 缓冲流 try { br = new MyBufferedReader(new FileReader("F:\\demo.txt")); String line = null; while ((line = br.readLine()) != null) { System.out.println(line); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
3. 范型实例
随着人民生活的挺高,大家也注重了饮食习惯,下面举一个通俗易懂的例子,让大家理解装饰设计模式。
吃饭的功能可以扩展,越来越讲究了
public class Person {//普通类 public void eat(){ System.out.println("吃饭"); } } /** * 装饰类 *进行封装了Person类对象,进行功能的扩展 */ public class superPerson { private Person person; public superPerson(Person person){ this.person=person; } public void superEat(){ System.out.println("喝点小酒"); person.eat(); System.out.println("看会电视"); System.out.println("打太极"); } } /** * 测试类 */ public class Text { public static void main(String[] args){ Person p=new Person();//普通类对象 superPerson pp=new superPerson(p);//装饰类对象 pp.superEat(); } } 结果: 喝点小酒 吃饭 看会电视 打太极
4. 装饰类和继承类
假如我们对已有的类进行扩展的方式使用继承的话,那么已有类(A)没增加一个子类(a extends A),我们都要对其子类进行再次继承(aa extends a),那么这样继承体系就太复杂,太臃肿了。
那么我们可以把现有类进行封装到一个类中,然后利用基类对象进行优化,
public class buffered{
private Aes;
publicbuffered(A es){
this.es=es;
}
下面根据es对象的方法,然后对其功能进行扩展,可以重写,也可以继续已有方法,写其他功能更完善的方法。
}
这样的体系就更简单易懂,这个就是装饰类。也是我们的装饰设计模式思想。
这也是从封装到装饰的过程。
装饰模式和继承的联系去区别:
装饰模式是对继承之间的关系的优化,这样就比继承更灵活,避免了继承体系臃肿,而且降低了类与类之间的关系。
装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强的功能,所以装饰类和被装饰类通常都属于一个体系中。
--------------------ASP.Net+Android+IOS开发、.Net培训、期待与您交流!
--------------------