Recognizing design Patterns through source code – Decorator patterns (JAVA I/O streams)

This is the sixth day of my participation in the August More text Challenge. For details, see: August More Text Challenge

1. Java/IO streams

  • What is the flow

Data is streamed between two devices (the essence of a stream is data transmission).

  • classification

According to different data types, it can be divided into character streams (in characters) and byte streams (in bytes). Byte streams can process all types of data

According to the flow of data can be divided into input stream and output stream

  • Java/IO knowledge architecture diagram

  1. InputStream is the parent class of all input byte streams. It is an abstract class

The subclasses below:

ByteArrayInputStream, StringBufferInputStream, and FileInputStream are basic input streams that read data from Byte arrays, StringBuffers, and files in the file system, respectively

PipedInputStream connects the pipe input stream to the pipe output stream; The pipe input stream then provides any data bytes written to the pipeoutputstream. A thread reads the data from the PipedInputStream object and writes the data to the appropriate pipeoutputstream

Both ObjectInputStream and FilterInputStream are decorative streams (for example, the usual BufferedInputStream)

  1. OutputStream is the parent class of all output byte streams. It is an abstract class. Its contents are similar to the byte InputStream InputStream except that one is input and the other is output

  2. Reader and Writer are character input and output streams

2. Decorator mode

  • If you want to extend a class without adding more subclasses, consider using the decorator pattern, which dynamically adds some extra functionality to an object. (Take a popular example: for example, a room is mainly used for sleeping, but I want the room to be able to play music while sleeping, so I installed a stereo in the room. But this activity does not change the original function of the room, but it can make me more comfortable when sleeping.)

There is no coupling between a decorator class and its decorated class as there is between inheritance, and the decorator class can be dynamically extended more flexibly than inheritance

Example code: 1. Create an interface for drawing graphics

public interface Shape {
    void draw();
}
Copy the code

2. Create an entity class that implements the interface

Public class implements Shape {@override public void draw() {system.out.println ("Shape: implements "); }}Copy the code

3. Create abstract decorator class and solid decorator class that implement the Shape interface

public abstract class ShapeDecorator implements Shape { Shape decoratedShape; public ShapeDecorator(Shape decoratedShape){ this.decoratedShape = decoratedShape; } public void draw(){ decoratedShape.draw(); Public class RedShapeDecorator extends ShapeDecorator {public RedShapeDecorator extends ShapeDecorator {public RedShapeDecorator extends ShapeDecorator {public RedShapeDecorator extends ShapeDecorator(Shape decoratedShape) { super(decoratedShape); } @Override public void draw() { decoratedShape.draw(); setRedBorder(decoratedShape); } private void setRedBorder(Shape decoratedShape){system.out.println (" color: red "); }}Copy the code

4. Dynamic expansion

Shape circle = new Circle(); // Output: Shape: round ShapeDecorator redCircle = new RedShapeDecorator(new Circle()); // Output: Shape: circle // color: redCopy the code

3. Code presentation

Look at the decorator mode in combination with the BufferedInputStream subclass of FilterInputStream in JAVA/IO streams:

  • BufferedInputStream it has all the functionality of an InputStream but it also provides buffering for the InputStream and the ability to support the mark and reset methods and when a BufferedInputStream is created, it creates an array of internal buffers. When bytes in the stream are read or skipped, the internal buffer is refilled as needed from the contained input stream

Source:

Reset (),mark() (BufferedInputStream)

  • The mark() method: marks the current position in this input stream
  • The reset() method: repositions the input stream to the point where the mark() method marker was last called on this input stream
  • Pos: The current position in the punch
  • Markpos: The value of the pos field when the last mark() method is called, always in the range -1 to pos
  • Marklimit: The maximum read-ahead allowed after calling the mark method before the reset method fails. When the difference between pos and markpos exceeds marklimit, the flag can be removed by setting markpos to -1

Reset (),mark() (InputStream)

BufferedInputStream is actually a decorative class of InputStream. BufferedInputStream creates a buffer when it reads a byte stream, and that buffer reduces the overhead of byte manipulation and improves efficiency.

4. To summarize

The decorator pattern provides an idea for extending a class. Compared to inheritance, the decorator class can reduce the coupling of the program, and the use of the extension is more flexible. The use of the decorator pattern depends on the circumstances, not the use of the decorator pattern for its own sake.