Decorator mode in Java Io

Source: Internet
Author: User
JDK provides a large number of class libraries for programmers. To maintain the reusability, scalability, and flexibility of class libraries, a large number of design modes are used, this article describes the decorator mode used in the jdk I/O package, and uses this mode to implement a new output stream class.

Decorator Mode

The decorator mode, also known as wrapper, is used to dynamically add some additional responsibilities to an object. It is more flexible than generating child classes.
Sometimes, we need to add some new functions for an object instead of the entire class. For example, we need to add a scroll bar to a worker area. We can use the inheritance mechanism to implement this function, but this method is not flexible enough. We cannot control the method and timing of adding a scroll bar in the render area. In addition, when you need to add more functions to the partition, such as borders, you need to create a new class. When you need to combine these functions, it will undoubtedly cause the class explosion.

We can use a more flexible method, that is, to embed the partition area into the scroll bar. The class of this scroll bar is equivalent toDecoration. This decoration (scroll bar) must be inherited from the same interface as the decorated component, so that users do not have to care about the decoration implementation, because it is transparent to them. The decoration will forward user requests to corresponding components (that is, call related methods), and may make some additional actions (such as adding a scroll bar) before and after the forwarding ). In this way, we can add any number of functions by embedding different decorations in the embedding area according to the combination. This dynamic method of adding functions to objects does not cause class explosion, but also has more flexibility.

The above method isDecorator ModeIt dynamically adds new features by adding decoration to the object. The following is a UML diagram of the decorator mode:

Component is a common parent class for components and decoration. It defines the methods that must be implemented by subclass.

Concretecomponent is a specific component class. You can add decoration to it to add new functions.

Decorator is a common parent class for all decorations. It defines the methods that must be implemented for all decorations. It also saves a reference to component to forward user requests to component, some additional actions may be executed before and after the request is forwarded.

Concretedecoratora and concretedecoratorb are specific decorations that can be used to decorate specific component.

Decorator mode in Java Io package

The decorator mode is used in the Java. Io package provided by JDK to encapsulate various input and output streams. The following uses Java. Io. outputstream and its subclass as an example to describe how to use the decorator mode in Io.

First, let's look at the code used to create an IO stream:

The following is a code snippet:
Try {
Outputstream out = new dataoutputstream (New fileoutputstream ("test.txt "));
} Catch (filenotfoundexception e ){
E. printstacktrace ();
}

This code is no longer familiar to those who have used JAVA input and output streams. We use dataoutputstream to encapsulate a fileoutputstream. This is a typical decorator mode. fileoutputstream is equivalent to component, and dataoutputstream is a decorator. You can easily understand the code by changing it to the following:

The following is a code snippet:
Try {
Outputstream out = new fileoutputstream ("test.txt ");
Out = new dataoutputstream (out );
} Catch (filenotfoundexception e ){
E. printstatcktrace ();
}

Since fileoutputstream and dataoutputstream have public parent classes outputstream, object decoration is almost transparent to users. Next let's take a look at how outputstream and its subclass form the decorator mode:

Outputstream is an abstract class that is the common parent class of all output streams. Its source code is as follows:

The following is a code snippet:
Public abstract class outputstream implements closeable, flushable {
Public abstract void write (int B) throws ioexception;
...
}

It defines the abstract method of write (int B. This is equivalent to the component class in decorator mode.

Bytearrayoutputstream, fileoutputstream, and pipedoutputstream are inherited directly from outputstream. Take bytearrayoutputstream as an example:

The following is a code snippet:
Public class bytearrayoutputstream extends outputstream {
Protected byte Buf [];
Protected int count;
Public bytearrayoutputstream (){
This (32 );
}
Public bytearrayoutputstream (INT size ){
If (size <0 ){
Throw new illegalargumentexception ("negative initial size:" + size );
}
Buf = new byte [size];
}
Public synchronized void write (int B ){
Int newcount = count + 1;
If (newcount> Buf. Length ){
Byte newbuf [] = new byte [math. Max (BUF. Length <1, newcount)];
System. arraycopy (BUF, 0, newbuf, 0, count );
Buf = newbuf;
}
Buf [count] = (byte) B;
Count = newcount;
}
...
}

It implements the write (int B) method in outputstream, so we can create an output stream object and complete the output in a specific format. It is equivalent to the concretecomponent class in decorator mode.

Next, let's take a look at filteroutputstream. The Code is as follows:

The following is a code snippet:
Public class filteroutputstream extendsOutputstream{
Protected outputstream out;
Public filteroutputstream (outputstream out ){
This. Out = out;
}
Public void write (int B) throws ioexception {
Out. Write (B );
}
...
}

It also inherits from outputstream. However, its constructor is very special. It needs to pass an outputstream reference to it and it will save the reference to this object. If no specific outputstream object exists, we cannot create filteroutputstream. Because out can be a reference to the filteroutputstream type or a reference to a specific output stream class such as bytearrayoutputstream, we can add a variety of decorations for bytearrayoutputstream using multi-layer nesting. This filteroutputstream class is equivalent to the decorator class in the decorator mode. Its write (int B) method simply calls the write (int B) method of the incoming stream, instead of doing more processing, it basically does not have convection decoration, so the subclass that inherits it must overwrite this method to achieve the purpose of decoration.

Bufferedoutputstream and dataoutputstream are two subclasses of filteroutputstream. They are equivalent to concretedecorator in decorator mode, and different decorations are made on the input output stream. Take the bufferedoutputstream class as an example:

The following is a code snippet:
Public class bufferedoutputstream extends filteroutputstream {
...
Private void flushbuffer () throws ioexception {
If (count> 0 ){
Out. Write (BUF, 0, count );
Count = 0;
}
}
Public synchronized void write (int B) throws ioexception {
If (count> = Buf. Length ){
Flushbuffer ();
}
Buf [count ++] = (byte) B;
}
...
}

This class provides a caching mechanism to write data into the output stream when the cache capacity reaches a certain number of bytes. First, it inherits filteroutputstream and overwrites the write (int B) method of the parent class. before calling the output stream to write data, it will check whether the cache is full. If it is not full, it will not be written. In this way, new functions are dynamically added to the output stream object.

Next, we will use the decorator mode to write a new output stream for Io.

Write a new output stream by yourself

After understanding the structure of outputstream and its subclass, we can write a new output stream to add new functions. This section provides an example of a new output stream, which filters out space characters in the statements to be output. For example, to output "Java Io outputstream", the filtered output is "javaiooutputstream ". The code for the skipspaceoutputstream class is as follows:

The following is a code snippet:

  import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* A new output stream, which will check the space character
* and won’t write it to the output stream.
* @author Magic
*
*/
public class SkipSpaceOutputStream extends FilterOutputStream {
  public SkipSpaceOutputStream(OutputStream out) {
   super(out);
  }
  /**
  * Rewrite the method in the parent class, and
  * skip the space character.
  */
  public void write(int b) throws IOException{
   if(b!=’ ’){
    super.write(b);
   }
  }
}

It inherits from filteroutputstream and overwrites its write (int B) method. In the write (int B) method, the input character is checked first. If it is not a space, it is output.

The following is a test procedure:

The following is a code snippet:

  import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* Test the SkipSpaceOutputStream.
* @author Magic
*
*/
public class Test {
  public static void main(String[] args){
   byte[] buffer = new byte[1024];
   /**
   * Create input stream from the standard input.
   */
   InputStream in = new BufferedInputStream(new DataInputStream(System.in));
   /**
   * write to the standard output.
   */
   OutputStream out = new SkipSpaceOutputStream(new DataOutputStream(System.out));
   try {
    System.out.println("Please input your words: ");
    int n = in.read(buffer,0,buffer.length);
    for(int i=0;i〈n;i++){
     out.write(buffer[i]);
    }
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
}

To run the above test program, you are required to enter information in the console window. The program filters out spaces in the information and outputs the final result to the console window. For example:

The following is a reference clip:

Please input your words:

A B C D E F

Abcdef

Summary

In the java. Io package, not only does outputstream use the decorator design mode, but also inputstream, reader, and writer use this mode. As a flexible and scalable class library, JDK uses a large number of design patterns, such as the MVC pattern in the swing package and the proxy pattern in RMI. The Research on models in JDK not only deepens the understanding of the models, but also facilitates a more thorough understanding of the structure and composition of the class libraries.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.