1 Overview
The purpose of decorator mode is to enhance the performance of classes.
Inheritance can also enhance the functionality of classes.
2 examples (easy to observe and understand the decoration mode)
The Writer class is a class that writes files. It has three subclasses: TxtWriter, MP3Writer and AVIWriter
The standard for writing files is defined in the writer, and the three subclasses implement the writing methods in the writer respectively
Class enhancement using inheritance
Writer
|-----TxtWriter
|-----MP3Writer
|-----AVIWriter
If the buffer for writing files is the same principle, we can extract the buffer as a decorator.
Three general classes
AviWriter.java
package cn.tx.demo; public class AviWriter { public void write() { System.out.println("write avi File complete"); } }
Mp3Writer.java
package cn.tx.demo; public class Mp3Writer { public void write() { System.out.println("write mp3 File complete"); } }
TxtWriter.java
package cn.tx.demo; public class TxtWriter { public void write() { System.out.println("write txt File complete"); } }
Requirements, such as strengthening the write methods of TxtWriter, MP3Writer and AVIWriter, and adding a buffer step to these three write methods.
2.1 mode 1: Inheritance
Create a Writer class
Writer.java
package cn.tx.demo; public class Writer { public void buffer() { System.out.println("Efficient cushioning with power"); } }
After each class inherits the Writer class
AviWriter.java
package cn.tx.demo; public class AviWriter extends Writer{ public void write() { buffer(); System.out.println("write avi File complete"); } }
Mp3Writer.java
package cn.tx.demo; public class Mp3Writer extends Writer{ public void write() { buffer(); System.out.println("write mp3 File complete"); } }
TxtWriter.java
package cn.tx.demo; public class TxtWriter extends Writer{ public void write() { buffer(); System.out.println("write txt File complete"); } }
Test.java
package cn.tx.demo; public class Test { public static void main(String[] args) { TxtWriter tw = new TxtWriter(); tw.write(); } }
The output result is:
Efficient cushioning with power
Writing txt file completed
Conclusion: this way of inheritance needs to change the methods in each class, which is aggressive to the methods in the class. We want to strengthen this function without changing the original things.
2.2 mode 2: decorator mode
Role:
1. Abstract role (define file writing standard): Writer
2. Specific roles (realizing the file writing standard): three subclasses: TxtWriter, MP3Writer and AVIWriter
3. Decorative role [Abstract] (efficient buffer): Note: it can also be defined as abstract. If it is abstract, there must be a specific Abstract role
4. Specific decorative role: to realize the enhancement method in the abstract decorator.
Code implementation:
directory structure
Writer.java
package cn.tx.demo; public abstract class Writer { public abstract void write() ; }
AviWriter.java
package cn.tx.demo; public class AviWriter extends Writer{ public void write() { System.out.println("write avi File complete"); } }
TxtWriter.java
package cn.tx.demo; public class TxtWriter extends Writer{ public void write() { System.out.println("write txt File complete"); } }
Mp3Writer.java
package cn.tx.demo; public class Mp3Writer extends Writer{ public void write() { System.out.println("write mp3 File complete"); } }
BufferTxWriter.java
package cn.tx.demo; public class BufferTxWriter extends Writer{ //Define a Writer property Writer writer; public BufferTxWriter(Writer writer) { this.writer = writer; } @Override public void write() { //Call the decoration method first buffer(); //Call the actual write method writer.write(); } /* * Decoration method */ public void buffer() { System.out.println("Plus efficient buffering"); } }
Test.java
package cn.tx.demo; public class Test { public static void main(String[] args) { Writer writer = new BufferTxWriter(new AviWriter()); writer.write(); System.out.println("--------------------------------"); writer = new BufferTxWriter(new TxtWriter()); writer.write(); System.out.println("--------------------------------"); writer = new BufferTxWriter(new Mp3Writer()); writer.write(); } }
The output result is:
Plus efficient buffering
Write avi file completed
--------------------------------
Plus efficient buffering
Writing txt file completed
--------------------------------
Plus efficient buffering
Writing mp3 file completed
3 case 23:00
3.1 case requirements
Copy pictures, copy text, On this basis, add log records when copying files, and record one by one. It is required to be completed automatically, not manually. Decorative pattern.
Files to be copied:
Copy to txfile folder under the project
Implementation code:
Copy.java
package cn.tx.demoeg; public abstract class Copy { public abstract void copy(String fileName) throws Exception; }
BinCopy.java
package cn.tx.demoeg; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; public class BinCopy extends Copy{ @Override public void copy(String fileName) throws Exception { FileInputStream in = new FileInputStream("d:\\res\\"+fileName); FileOutputStream out = new FileOutputStream("txfile\\"+fileName); byte[] bs = new byte[1024]; while(in.read(bs) != -1) { out.write(bs); } out.close(); in.close(); } }
TxtCopy.java
package cn.tx.demoeg; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.PrintWriter; public class TxtCopy extends Copy{ @Override public void copy(String fileName) throws Exception { BufferedReader br = new BufferedReader(new FileReader("d:\\res\\"+fileName)); PrintWriter pw = new PrintWriter("txfile\\"+fileName); String line = null; while((line = br.readLine()) != null){ pw.print(line); } pw.close(); br.close(); } }
LogCopy.java
package cn.tx.demoeg; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; public class LogCopy extends Copy{ private Copy copy; public LogCopy(Copy copy) { super(); this.copy = copy; } @Override public void copy(String fileName) throws Exception { copy.copy(fileName); log(fileName); } /* * Record all the copied files in record Log inside */ public void log(String fileName) throws IOException { //Create file output stream BufferedWriter bw = new BufferedWriter(new FileWriter("record.log",true)); String str = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date())+ "--Copied files--" +fileName; bw.write(str); bw.newLine(); bw.flush(); bw.close(); } }
Test.java
package cn.tx.demoeg; public class Test { public static void main(String[] args) throws Exception { LogCopy logCopy = new LogCopy(new BinCopy()); logCopy.copy("rz.jpg"); logCopy = new LogCopy(new TxtCopy()); logCopy.copy("test.txt"); } }
Output result:
record.log
2021-04-17 12:36:59--Copied files--rz.jpg 2021-04-17 12:38:34--Copied files--rz.jpg 2021-04-17 12:38:34--Copied files--test.txt
Later, if you want to add a method to Copy other things, you can directly add it to the new class XXX Just write your own Copy function in Java, and then directly inherit the Copy class.
When using it, it is the same as others. It has the function of logging.
Test:
In the Test class
logCopy = new LogCopy(new Xxx());
logCopy.copy("file name to copy");
The same result can be found in record Log.