装饰者模式Decorator

xiaoxiao2021-02-28  150

实例分析

         Decorator装饰或者Wrapper包装这个些词太容易让人想到的是图形用户界面,这些控件方面的应用了。但这仅仅只是一种形象的表达而已,不局限于此。

1 For Example:  

  Streams是大多数I / O设备的基础抽象结构,它提供了将对象转换成为字节或字符流的操作接口,

使我们可以将一个对象转变成一个文件或内存中的字符串,可以在以后恢复使用。一个简单直接的

方法是定义一个抽象的Stream类,它有两个子类MemoryStream与FileStream。但假定我们还希望能够做下面一些事情:

• 用不同的压缩算法(行程编码, Lempel-Ziv等)对数据流进行压缩。

• 将流数据简化为7位A S C I I码字符,这样它就可以在A S C I I信道上传输。

Decorator模式提供的将这些功能添加到Stream中方法很巧妙。下面的类图给出了一个解决问题的方法。

    

  Stream抽象类维持了一个内部缓冲区并提供一些操作( PutInt, PutString)用于将数据存入流中。

一旦这个缓冲区满了,Stream就会调用抽象操作HandleBufferFull进行实际数据传输。

在FileStream中重定义了这个操作,将缓冲区中的数据传输到文件中去。

  这里的关键类是StreamDecorator,它维持了一个指向组件流的指针并将请求转发给它,

StreamDecorator子类重定义HandleBufferFull 操作并且在调用StreamDecorator的HandleBufferFull操作之前执行一些额外的动作。

  例如,CompressingStream子类用于压缩数据,而ASCII7Stream将数据转换成7位ASCII码。

现在我们创建FileStream类,它首先将数据压缩,然后将压缩了的二进制数据转换成为7位ASCII码,

我们用CompressingStream和ASCII7Stream装饰FileStream:

  

Stream* aStream = new ASCII7Stream ( new CompressingStream ( new FileStream("aFileStream") ) );aStream->PutInt(12);aStream->PutString("aString");

 

2 相关模式:

Adapter模式:Decorator模式不同于Adapter模式,因为装饰仅改变对象的职责而不改变它的接口;而适配器将给对象一个全新的接口。Composite模式:可以将装饰视为一个退化的、仅有一个组件的组合。然而,装饰仅给对象添加一些额外的职责—它的目的不在于对象聚集。Strategy模式:用一个装饰你可以改变对象的外表;而Strategy模式使得你可以改变对象的内核。这是改变对象的两种途径。 java io中  OutputStream FileOutputStream ,ByteOutputStream 和   FilterOutputStream                         BufferedOutputStream(可以有缓冲区) ,DataOutputStream(可以直接从文件中读取各种数据类型) 关系就是上面的装饰关系。   private static void testBufferedOutputStream() {        // 创建“文件输出流”对应的BufferedOutputStream      // 它对应缓冲区的大小是16,即缓冲区的数据>=16时,会自动将缓冲区的内容写入到输出流。      try {        File file = new File( "out.txt" );        OutputStream out =           new BufferedOutputStream(             new FileOutputStream(file), 16 );          // 将ArrayLetters数组的前10个字节写入到输出流中        out.write(ArrayLetters, 0 , 10 );        // 将“换行符\n”写入到输出流中        out.write( '\n' );          // TODO!        //out.flush();          readUserInput() ;          out.close();      } catch (FileNotFoundException e) {        e.printStackTrace();      } catch (SecurityException e) {        e.printStackTrace();      } catch (IOException e) {        e.printStackTrace();      }    }

这里的可以让写入功能自动缓存到buffer中,设置合适的大小,可以达到减少磁盘交互。加快写入速度。不用手动实现写入文件的代码了。

public void copyFile(String oldPath, String newPath) { try { int bytesum = 0; int byteread = 0; File oldfile = new File(oldPath); if (oldfile.exists()) { //文件存在时 InputStream inStream = new FileInputStream(oldPath); //读入原文件 FileOutputStream fs = new FileOutputStream(newPath); byte[] buffer = new byte[1444]; int length; while ( (byteread = inStream.read(buffer)) != -1) { bytesum += byteread; //字节数 文件大小 System.out.println(bytesum); fs.write(buffer, 0, byteread); } inStream.close(); } } catch (Exception e) { System.out.println("复制单个文件操作出错"); e.printStackTrace(); } }

同样 还有input也是类似的模式

转载请注明原文地址: https://www.6miu.com/read-35257.html

最新回复(0)