java design pattern_ Decorator mode

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.

Keywords: Java Design Pattern

Added by siric on Sat, 05 Mar 2022 01:16:39 +0200