Two design modes of Java I/O

Source: Internet
Author: User

Two design modes of the Java I/O Library:
Click Open Link
The overall design of the Java I/O Library conforms to the decorator and adapter modes. As mentioned above, the class for processing a stream in this database is called a stream class. The fileinputstream, fileoutputstream, datainputstream, and dataoutputstream mentioned in the Introduction are examples of stream processors.

1. modifier mode: in the hierarchical structure represented by inputstream, outputstream, reader, and writer, some stream processors can play a decorative role on other stream processors to form a new one, stream processor with improved features. The modifier mode is the overall design mode of the Java I/O library. Such a principle is in line with the modifier mode.

2. Adapter mode: in the hierarchical structure represented by inputstream, outputstream, reader, and writer, some stream processors adapt to other types of processors. This is the application of the adapter mode.

The adapter mode is applied to the original stream processor design and forms the starting point of all stream processors in the I/O library.
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 to a decoration of the worker area. 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 is the decorator mode, which dynamically adds new functions by adding decoration to the object.

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 not familiar to anyone who has used JAVA input/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 extends outputstream {

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) The method simply calls the write (int B) method of the incoming stream, but does not do more processing. Therefore, it essentially does not have streaming decoration, therefore, 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.

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.

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.