java design pattern Decorator Pattern

Keywords: Java Junit

Decorator mode

Reference documents: http://c.biancheng.net/view/1366.html

 

In real life, it is often necessary to add new functions or beautify the appearance of existing products, such as house decoration, photo frame and so on. In the process of software development, sometimes you want to use some existing components. These components may only accomplish some core functions. But it can expand its function dynamically without changing its structure. All of these can be realized by decoration mode.

Definition and characteristics of decoration mode

The definition of Decorator pattern refers to a pattern that adds some responsibilities to an object dynamically without changing the existing object structure (that is, adding additional functions). It belongs to the object structure pattern.

The main advantages of Decorator mode are as follows:

  • It is more flexible to extend the function of objects by decoration mode than by inheritance.
  • It can design many different specific decoration classes and create many combinations of different behaviors.


The main drawback is that the decoration mode adds many subclasses, and if overused, the program will become very complex.

The structure and Realization of decoration mode

In general, the function of extending a class is implemented by inheritance. However, inheritance has static characteristics and high coupling. With the increase of extended functions, subclasses will expand. The goal of decoration pattern is to create a wrapper object (i.e. decoration object) to wrap the real object by using composition relation, and to provide additional functions for the real object while keeping its class structure unchanged. Next, we will analyze its basic structure and implementation method.


1. Structure of mode

Decoration mode mainly includes the following roles.

  1. Abstract Component role: define an abstract interface to standardize the objects ready to receive additional responsibilities.
  2. Concrete Component role: implement abstract Component and add some responsibilities for it through decoration role.
  3. The role of Decorator: inherits the abstract component and contains instances of the concrete component. The function of the concrete component can be extended through its subclasses.
  4. Concrete decorator role: implement the relevant methods of abstract decoration and add additional responsibilities to concrete component objects.


The structure of decoration mode is shown in Figure 1.
 

                             
Figure 1 Structure of decoration mode

Application scenario of decoration mode

The structure and characteristics of decoration mode are explained in the front, and the applicable application scenarios are introduced below. Decoration mode is usually used in the following situations.

  • When you need to add additional responsibilities to an existing class, but you cannot extend it by generating subclasses. For example, if the class is hidden or the class is the ultimate class or inherits, a large number of subclasses will be generated.
  • When it is necessary to arrange and combine a set of existing basic functions to generate a lot of functions, it is difficult to achieve the inheritance relationship, but it is very good to use the decoration mode.
  • When the functional requirements of an object can be added or revoked dynamically.


Decoration mode in Java The most famous application of the language is the design of Java I/O standard library. For example, the subclass FilterInputStream of InputStream, the subclass FilterOutputStream of OutputStream, the subclass BufferedReader and FilterReader of Reader, and the subclass BufferedWriter, FilterWriter and PrintWriter of Writer are all abstract decoration classes.

demo

step 1: abstract Component role: define an abstract interface to standardize the object ready to receive additional responsibilities.

package java_basic.stu_design_mode.stu_Decorator;
//Abstract component
public interface Component {
    void operation();
}

step 2 concrete component role: implement abstract component and add some responsibilities for it by decorating role.

package java_basic.stu_design_mode.stu_Decorator;
//The object to which a specific component is decorated
public class ConcreteComponent implements Component{
    @Override
    public void operation() {
        System.out.println("Specific components");
    }
}

step 3: the role of Decorator: inherits abstract components and contains instances of concrete components. The function of concrete components can be extended through its subclasses.

package java_basic.stu_design_mode.stu_Decorator;
//Abstract decorative role
public abstract class Decorator implements Component {
    private  Component component;
    Decorator( Component component){
        this.component = component;
    }

    @Override
    public void operation() {
       component.operation();
    }
}

step 4 concrete decorator role: implement relevant methods of abstract decoration and add additional responsibilities to specific component objects.

package java_basic.stu_design_mode.stu_Decorator;
//Specific decorative role
public class ConcreteDecorator extends Decorator {
    ConcreteDecorator(Component component) {
        super(component);
    }
    @Override
    public void operation() {
        super.operation();
        addFunctionZero();
    }

    public void addFunctionZero(){
        System.out.println("this is add zero method");
    }
}

Write another layer of specific decoration

package java_basic.stu_design_mode.stu_Decorator;
//Specific decorative role
public class ConcreteDecorator1 extends Decorator {
    ConcreteDecorator1(Component component) {
        super(component);
    }
    @Override
    public void operation() {
        super.operation();
        addFunctionZero();
    }

    public void addFunctionZero(){
        System.out.println("this is add one method");
    }
}

step 5 call

package java_basic.stu_design_mode.stu_Decorator;

import org.junit.Test;

public class Main {
    @Test
    public void method() {
        //Decorated class
        Component concreteComponent = new ConcreteComponent();

        Component concreteDecorator = new ConcreteDecorator(concreteComponent);
        concreteDecorator.operation();

        System.out.println("******************************************");

        Component concreteDecorator1 = new ConcreteDecorator1(concreteDecorator);
        concreteDecorator1.operation();
        System.out.println("******************************************");
    }
}

Call result

Specific components
this is add zero method
******************************************
Specific components
this is add zero method
this is add one method

 

Extension of decoration mode

The four characters contained in decoration mode do not exist at any time. In some application environments, the pattern can be simplified, such as the following two cases.

(1) If there is only one concrete component but no abstract component, the abstract decoration can inherit the concrete component, and its structure diagram is shown in Figure 4.
 

                                     
Figure 4 decoration mode with only one specific component


(2) If there is only one specific decoration, the abstract decoration and the specific decoration can be combined, and the structure diagram is shown in Figure 5.
 

                           
Figure 5 decoration mode with only one specific decoration

Posted by satyac46 on Sun, 28 Jun 2020 20:19:16 -0700