Decoration mode (old crush)
| -- What is the decoration mode.
Decoration mode: whether it is you or you. Please use the classic words of Lao Cui ).
It appears from inheritance, first inherited, and then decorated.
Recall inheritance
Benefits: Improves reusability and enables reuse. Later extensions can be used through method rewriting.
Disadvantage: because of the inheritance relationship between classes, their relationships are enhanced, and their coupling is high. Not in line with java's purpose: low coupling and high cohesion.
Comparison:
A: There is a Witer system.
| -- TxtWrite
| -- Mp3Write
| -- DIDWrite
The above is a common subclass implementation. The caller thinks the execution is too slow and needs to enhance the three (efficient | buffering ). Modify as follows:
Class myBuffereWrite exetends Write {
// Receiving subclass: Fu f = new Zi ();
Private Write ziWrite;
Public BuffereWrite (Write ziWrite)
{
This. ziWrite = ziWrite;
}
Public void writeLine (String line)
{
// Use ziWrite for cosmetic processing, and save a row of data to write.
}
Public void close ()
{
ZiWrite. clese (); // polymorphism (called or subclass )!
}
Public void flash (){
ZiWrite. flash (); // polymorphism (called or subclass )!
}
... // Rewrite the abstract method of Write. In myBuffereWrite, the call in the method is to transfer ziWrite. Just calling it
I had some surgery on it before.
}
| -- Summary
1: for example, if you use the efficient Write function, you can create myBuffereWrite and pass your efficient objects, such as FileWrite ();
2: The decoration mode reflects the enhancement (High Cohesion) of an object (function), and then the tightness is relatively weak (low coupling ).
3: JDK uses a lot of decorations, such as BufferedWriter (Writer out), PrintStream (OutputStream out), and ObjectInputStream (InputStream in.
| -- Sample Code
Simulate buffererereader decoration class
Package com. decoration; import java. io. IOException; import java. io. reader;/*** @ author hubiao * simulate buffererereader decoration class ** analysis: simulate a class, that is, to customize a class and implement its unique method: ReadLine (); * 1: simulation: Special Method * 2: What do you have: According to the decorative characteristics, a custom class inherits an abstract class, because the underlying layer of BuffereReader's readLine inherits from Reader. * What we need to do is inherit Reader and write a ReadLine method that is the same as BuffereReader. */Public class MyBuffere extends Reader {/* Reader is the parent class of an abstract class and implements all the classes that require efficiency. Is its subclass. */Private Reader reader = null; public MyBuffere (Reader reader) {this. reader = reader;} public int read (char [] cbuf, int off, int len) throws IOException {return reader. read (cbuf, off, len);} public String readLine () throws IOException {/*** 1: here you need to think about it. Use * A: read (char [] cbuf, int off, int len); read a buffer at a time * B: read (); // read a string at a time * 2: Analysis * What is the purpose of simulating readLine? It is not an efficient method for reading a row at a time in readerLine of BufferedReader. * It is not appropriate to use method A because it reads the length defined by A char capacity at A time, and the encapsulated code is difficult to know how long each row of Data Text the caller wants to read. * The advantage of using the B method is to read one character at a time. When \ r \ n is returned, it indicates that the reading of one row is complete, how can we store each character in a row of data? * It's terrible to use String, because we know that String is a constant pool in java. 1. The value assignment is unchangeable. Therefore, the highly efficient StringBuilder * concatenates each character into the StringBuffer and returns it to the caller. * /// Single-character container StringBuffer buffer = new StringBuffer (); // each character int read = 0; while (read = reader. read ())! =-1) {char chr = (char) read; if (chr = '\ R') continue; if (chr =' \ n') return buffer. toString (); elsebuffer. append (chr);} // prevents the last row from being read, and \ r \ n is not displayed. Then, check whether there is a value in the buffer zone? If yes, return again. If (buffer. length ()> 0) return buffer. toString (); elsereturn null;} public void close () throws IOException {reader. close ();}}
Simulate LineNumberReader
/*** @ Author hubiao * simulates LineNumberReader *. Similarly, the simulation is to define a class. The special method provided by the simulation requirement is to obtain each row and then read each row. */Public class MyLineNumberReader extends Reader {/* receives the passed subclass object, Fu f = new Zi (); // polymorphism */private Reader reader; private int lineNumber; // The row number is public MyLineNumberReader (Reader reader) {this. reader = reader;} public int read (char [] cbuf, int off, int len) throws IOException {return reader. read (cbuf, off, len);} public String readLine () throws IOException {// single character container StringBuffer buffer = new StringBuffer (); // each character int Read = 0; while (read = reader. read ())! =-1) //-1 indicates reading to the end of the stream! {Char chr = (char) read; if (chr = '\ R') continue; if (chr =' \ n') {lineNumber ++; return buffer. toString ();} elsebuffer. append (chr);} // prevents the last row from being read, and \ r \ n is not displayed. Then, check whether there is a value in the buffer zone? If yes, return again. If (buffer. length ()> 0) {lineNumber ++; return buffer. toString ();} elsereturn null;} public void close () throws IOException {reader. close ();} public int getLineNumber () {return lineNumber;} public void setLineNumber (int lineNumber) {this. lineNumber = lineNumber ;}}