Decorator mode (common usage)

Decorator mode

Most office workers have the habit of sleeping in. They are very nervous at work every morning, so many people will solve the breakfast problem in a convenient way in order to get more sleep. Some people may have pancakes for breakfast. They can add eggs or sausages to the pancakes, but no matter how "overweight", they are still a pancake. In real life, it is often necessary to add new functions to existing products or beautify their appearance, such as house decoration, photos and photo frames, which are all decorator modes.

Definition of Decorator Pattern: it refers to the pattern that dynamically adds some responsibilities (i.e. adds its additional functions) to the object without changing the existing object structure. It belongs to object structure pattern.

Usually, the function of extending a class is implemented by inheritance. However, inheritance has static characteristics, high coupling, and subclasses will expand with the increase of extended functions. The goal of decorator pattern is to create a wrapper object (i.e. decoration object) to wrap the real object and provide it with additional functions on the premise of keeping the class structure of the real object unchanged. The basic structure and implementation method are analyzed below.

Decorator mode mainly includes the following roles.

  1. Abstract Component role: define an abstract interface to standardize objects ready to receive additional responsibilities.
  2. Concrete component role: implement abstract components and add some responsibilities to them by decorating roles.
  3. Abstract Decorator role: inherits abstract components and contains instances of specific components. You can extend the functions of specific components through its subclasses.
  4. Concrete decorator role: implement relevant methods of abstract decoration and add additional responsibilities to specific component objects.
//Functional interface
public interface Robot {
    void doSomething();
}

//Robot human
public class FirstRobot implements Robot{
    @Override
    public void doSomething() {
        System.out.println("dialogue");
        System.out.println("sing");
    }
}

//Decorator
public  class RobotDecorator implements Robot{
    private Robot robot;

    public RobotDecorator(Robot robot) {
        this.robot = robot;
    }

    @Override
    public void doSomething() {
        robot.doSomething();
    }
    public void doMorething(){
        robot.doSomething();
        System.out.println("dance,Mopping");
    }
}

public class DecoratorPattern {
    public static void main(String[] args) {
        new RobotDecorator(new FirstRobot()).doMorething();
    }
}

result:
dialogue
 sing
 dance,Mopping

The above example lacks specific decorative roles and is the simplest one

//This is an online case
public class DecoratorPattern {
    public static void main(String[] args) {
        Component p = new ConcreteComponent();
        p.operation();
        System.out.println("---------------------------------");
        Component d = new ConcreteDecorator(p);
        d.operation();
    }
}
//Abstract component role
interface Component {
    public void operation();
}
//Specific component role
class ConcreteComponent implements Component {
    public ConcreteComponent() {
        System.out.println("Create concrete component roles");
    }
    public void operation() {
        System.out.println("Calling methods for specific component roles operation()");
    }
}
//Abstract decorative role
class Decorator implements Component {
    private Component component;
    public Decorator(Component component) {
        this.component = component;
    }
    public void operation() {
        component.operation();
    }
}
//Specific decorative role
class ConcreteDecorator extends Decorator {
    public ConcreteDecorator(Component component) {
        super(component);
    }
    public void operation() {
        super.operation();
        addedFunction();
    }
    public void addedFunction() {
        System.out.println("Add additional functions to specific component roles addedFunction()");
    }
}

The main advantages of decorator mode are:

  • Decorator is a powerful supplement to inheritance. It is more flexible than inheritance. It dynamically extends the function of an object without changing the original object, plug and play
  • Different effects can be achieved by using different decorative classes and the arrangement and combination of these decorative classes
  • The decorator mode fully complies with the opening and closing principle

Its main disadvantage is that the decorator pattern will add many subclasses, and overuse will increase the complexity of the program.

Specific examples include:

java I/O data flow

Keywords: Java unit testing

Added by latinofever on Mon, 06 Sep 2021 05:41:56 +0300