黑马程序员_82_装饰设计模式

 ——- android培训java培训、期待与您交流! ———-

装饰设计模式

概述及分析

装饰设计模式就是对原有的类进行功能的加强,修饰.
示例:

class Person{
       void chifan(){
            System.out.println( "吃饭");
      }
}

//采用装饰的方式增强Person类
//这个类的出现是为了增强Person而出现的
class NewPerson{
       private Person p;

      NewPerson(Person p){
             this.p = p;
      }

       public void chifan(){
            System.out.println( "开胃酒");
            p.chifan();
            System.out.println( "甜点");
      }
}

//采用继承的方式增强Person类
class NewPerson2 extends Person{
       public void chifan(){
            System.out.println( "开胃酒");
             super.chifan();
            System.out.println( "甜点");
      }
}

public class PersonDemo{
       public static void main(String[] args){
            Person p = new Person();
            NewPerson np1 = new NewPerson(p);
            np1.chifan();

            System.out.println( "---------------");

            NewPerson2 np2 = new NewPerson2();
            np2.chifan();
      }
}

运行结果如下:
这里写图片描述
装饰和继承都能实现一样的特点:进行功能的扩展增强。有什么区别呢?

首先有一个继承体系:
Writer
      |--TextWriter:用于操作文本
      |--MediaWriter:用于操作媒体
如果想要对操作的动作进行效率的提高,按照面向对象,可以通过继承的方式对具体的对象进行功能的扩展,那么就需要加入缓冲技术。
Writer
      |--TextWriter:用于操作文本
           |--BufferTextWriter:加入了缓冲技术的操作文本的对象
      |--MediaWriter:用于操作媒体
           |--BufferMediaWriter:加入了缓冲技术的操作媒体的对象
以上方式并不理想,如果这个体系需要再进行功能扩展,又多了更多流对象。
这样就会发现只为提高功能,导致继承体系越来越臃肿,不够灵活。

重新思考问题:
既然加入的都是同一种技术–缓冲。
前一种是让缓冲和自己的流对象相结合。
可不可以将缓冲进行单独的封装,哪个对象需要缓冲就将哪个对象和缓冲关联。

class Buffer {
     Buffer(TextWriter w){}
     Buffer(MediaWriter w){}
}

简化后:

class BufferedWriter extends Writer{
     BufferedWriter(Writer w){}
}

Writer
|–TextWriter:用于操作文本
|–MediaWriter:用于操作媒体
|–BufferedWriter:用于提高效率

可见:装饰比继承灵活。
特点:装饰类和被装饰类都必须所属同一个接口或者父类。

练习

练习:
自定义一个读取缓冲区类,模拟一个BufferedReader。

分析:
缓冲区中无非就是封装了一个数组,并对外提供了更多的方法对数组进行访问,其实这些方法最终操作的都是数组的角标。

缓冲的原理:
其实就是从源中获取一批数据到缓冲区中,再从缓冲区中不断地取出一个一个数据。
在此次取完后,再从源中继续取一批数据进缓冲区,当源中的数据取完时,用-1作为结束标记。

代码:

import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

class MyBufferedReader{

      private Reader r;

      //定义一个数组作为缓冲区
      private char[] buf = new char[1024];

      //定义一个指针用于操作这个数组中的元素,当操作到最后一个元素后,指针应该归零
      private int pos = 0;

      //定义一个计数器用于记录缓冲区中的数据个数,当该数据减到0,就从源中继续获取数据到缓冲区中
      private int count = 0;

      MyBufferedReader(Reader r){
             this .r = r; 
      }

      //该方法从缓冲区中一次取一个字符
      public int myRead() throws IOException {
             //从源中获取一批数据到缓冲区中,需要先做判断,只有计数器为0时,才需要从源中获取数据
             if (count == 0){
                  count = r.read(buf);

                  //每次获取数据到缓冲区后,角标归零
                  pos = 0;
             }

             if (count < 0)
                   return -1;

             char ch = buf[pos];

             pos++;
             count--;

             return ch;
      }

       public String myReadLine() throws IOException {
            StringBuilder sb = new StringBuilder();

             int ch = 0;
             while ((ch = myRead()) != -1){
                   if (ch == '\r' )
                         continue ;
                   if (ch == '\n' )
                         return sb.toString();
                   //将从缓冲区读到的字符,存储到缓存行数据的缓冲区中
                  sb.append(( char )ch);
            }

             if (sb.length() != 0){
                   return sb.toString();
            }
             return null ;
      }

       public void myClose() throws IOException {
            r.close();
      }
}

public class MyBufferedReaderDemo{
       public static void main(String[] args) throws IOException {
            FileReader fr = new FileReader("buf.txt" );

            MyBufferedReader bufr = new MyBufferedReader(fr);

            String line = null ;

             while ((line = bufr.myReadLine()) != null){
                  System.out.println(line);           
            }

            bufr.myClose();
      }
}

运行结果:
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值