现在的位置: 首页 > 综合 > 正文

黑马程序员_<<装饰设计模式>>

2018年09月16日 ⁄ 综合 ⁄ 共 2917字 ⁄ 字号 评论关闭

--------------------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培训、期待与您交流!
--------------------

抱歉!评论已关闭.