Java decoration mode

You look at the scenery on the mountain. People who look at the scenery look at you on the mountain. The moon decorates your Windows, you decorate other people's dreams.

 

Decorator Pattern, also known as wrapper pattern, allows you to add new functions to an existing object without changing its structure. This type of design pattern belongs to structural pattern, which is a wrapper of existing classes, different from agent.

This pattern creates a decoration class to wrap the original class, and provides additional functions while maintaining the integrity of class method signature.

introduce

Intent: dynamically add some additional responsibilities to an object. In terms of added functionality, the decorator pattern is more flexible than generating subclasses.

Main solution: in order to extend a class, we often use inheritance to implement it. Because inheritance introduces static features into a class, and with the increase of extension functions, subclasses will expand.

When to use: extend a class without adding many subclasses.

How to solve it: divide the specific functions and responsibilities, and inherit the decorator mode.

Key code: 1. The Component class acts as an abstract role and should not be implemented specifically. 2. Modify class references and inherits Component class, and specific extension class overrides parent class method.

Advantages: the decoration class and the decorated class can develop independently without coupling each other. The decoration mode is an alternative mode of inheritance. The decoration mode can dynamically expand the function of an implementation class.

Disadvantages: multi-layer decoration is more complex.

Usage scenario: 1. Extend the function of a class. 2. Dynamic add function, dynamic undo.

Note: can replace inheritance.

Structure chart

participant:

Component: define an object interface to dynamically add responsibilities to these objects

ConcreteComponent: define an object and add some responsibilities to it

Decorator: maintain a pointer to the Component object and define an interface consistent with the Component interface

ConcreteDecoratorA,ConcreteDecoratorB. . . CD, etc.: add responsibilities to components

 

We use the following example to demonstrate the use of decorator mode, to decorate images such as coloring, framing, and then printing.

1. define an abstract class:

/**
 * @author dgm
 * @describe "Image, year on year dependent“
 */
public abstract class PhotoImage {
	//Image description
	public abstract String getDescription();
}

2. Create the wrapper implementation class of the abstract class.

/**
 * 
 * @author dgm
 * @describe "Analogy ConcreteComponent“
 */
public class PhotoImageWrapper extends PhotoImage {

	// Image title
	String title;
	// Picture file name
	String fileName;
	// Image width and height
	int pixWidth, pixHeight;

	public PhotoImageWrapper() {
		// Empty; used in Decorators.
	}

	public PhotoImageWrapper(String title, String fileName) {
		super();
		this.title = title;
		this.fileName = fileName;
	}

	@Override
	public String toString() {
		return getDescription();
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}

	public int getPixWidth() {
		return pixWidth;
	}

	public void setPixWidth(int width) {
		this.pixWidth = width;
	}

	public int getPixHeight() {
		return pixHeight;
	}

	public void setPixHeight(int height) {
		this.pixHeight = height;
	}

	@Override
	public String getDescription() {
		return getTitle();
	}
}

3. Create decoration class

/**
 * 
 * @author dgm
 * @describe "Image decoration, similar to Decorator“
 */
public abstract class ImageDecorator extends PhotoImage {
	protected PhotoImage target;
	
	public ImageDecorator(PhotoImage target) {
		this.target = target;
	}
	
	@Override
	public String getDescription() {
		return target.getDescription();
	}
	
	@Override
	public String toString() {
		return getDescription();
	}
}

4. Expand the specific implementation of the decoration class (coloring, framing, printing, in fact, adding, such as selling)

ColorDecorator.java,FrameDecorator.java,PrintDecorator.java

public class ColorDecorator extends ImageDecorator {
	String color;
	
	public ColorDecorator(String color, PhotoImage target) {
		super(target);
		this.color = color;
	}

	@Override
	public String getDescription() {
		return target.getDescription() + ", Coloring(" + color + ")";
	}
}

public class FrameDecorator extends ImageDecorator {
	private String desc;
	public FrameDecorator(String desc, PhotoImage target) {
		super(target);
		this.desc = desc;
	}

	@Override
	public String getDescription() {
		return target.getDescription() + ", "+desc+", ";
	}
}

/**
 * 
 * @author dgm
 * @describe "Print image, similar to ConcreteDecorator“
 */
public class PrintDecorator extends ImageDecorator {
	private String desc;
	private double printWidth, printHeight;
	
	public PrintDecorator(String desc,double printWidth, double printHeight, PhotoImage target) {
		super(target);
		this.desc = desc;
		this.printWidth = printWidth;
		this.printHeight = printHeight;
	}

	@Override
	public String getDescription() {
		return target.getDescription() + desc+ " " + String.format("(%4.1f x %4.1f in)", getPrintWidth(), getPrintHeight());
	}

	public double getPrintWidth() {
		return printWidth;
	}

	public void setPrintWidth(double printWidth) {
		this.printWidth = printWidth;
	}

	public double getPrintHeight() {
		return printHeight;
	}

	public void setPrintHeight(double printHeight) {
		this.printHeight = printHeight;
	}
}

 

5. Test the image decoration effect:

/**
 * 
 * @author dgm
 * @describe "Decoration mode (decorated with pictures and images) test“
 */
public class PhotoImageDecoratorTest {

	public static void main(String[] args) {
		//Image object, then coloring, binding, and finally printing
		PrintDecorator image = new PrintDecorator("High definition for color laser printing", 19, 11,
				new FrameDecorator("Gold Framed",new ColorDecorator("Sky blue", new PhotoImageWrapper(
						"Mona Lisa's smile", "1968/ifd.00042.jpg"))));
		System.out.println(image);
	}

	private static void addToPrintOrder(PrintDecorator image) {
		System.out.println(image);
	}
}

Output effect:

Only 0 is the raw material, 123 decoration

Warehousing https://github.com/dongguangming/design-pattern/tree/master/src/code/decorator

Case: for example, the io stream in the native jdk uses the decoration mode to decorate a stream

        InputStream inputStream = new FileInputStream("f:\\InstallCert.java");
        InputStream bis = new BufferedInputStream(inputStream);
        InputStream in = new DataInputStream(bis);
        InputStreamReader isr = new InputStreamReader(in);
        BufferedReader br  = new BufferedReader(isr);
        String line = null;
        while ((line = br.readLine()) != null) {
            //Print text to console
            System.out.println(line);
        }

Chain length

BufferedReader br = new BufferedReader(new InputStreamReader(new DataInputStream(
        new BufferedInputStream(new FileInputStream("f:\\InstallCert.java")))));

And the extension development of component in javafx.swing development also uses decoration mode

cache also has decorative shadow in MyBatis framework

Spring also has decorations, which are more powerful (without Bean, there is no other extension): BeanDefinitionDecorator (to be understood separately, BeanDefinition and Decorator) is the decoration of Bean definition stage, and of course, there are other decorations such as decorating WebSocket objects.

 

Decoration mode, especially in the log, cache, io stream and other scenes is too suitable!!!

Pay special attention to its differences from other models:

 

Summary: if you want to add additional behavior responsibilities to the original object, but don't want to change it, you can use this mode. Then decorate the original object, use a lot of scenes, play it by yourself and go your own way, but others will talk about it

 

reference resources:

0. Decoration mode https://baike.baidu.com/item/%E8%A3%85%E9%A5%B0%E6%A8%A1%E5%BC%8F/10158540

1. How to use Decorator mode http://www.uml.org.cn/sjms/20041655.htm

2.  javax.swing.JScrollPane  https://docs.oracle.com/javase/8/docs/api/javax/swing/JScrollPane.html

 

3. Decorator Design Pattern Applied https://www.javacodegeeks.com/2014/08/decorator-design-pattern-applied.html

4.  The Decorator Pattern in Depth  https://blogs.oracle.com/javamagazine/the-decorator-pattern-in-depth

5.  Decorator Design Pattern in Java with Example  https://www.java67.com/2013/07/decorator-design-pattern-in-java-real-life-example-tutorial.html?m=1

Tags: Java Oracle Windows github

Posted on Sat, 16 May 2020 07:15:37 -0400 by sqlmc