Design pattern 2 - Decorator Pattern

Decorator mode: add functions on the basis of not changing the original object, and dynamically add or revoke functions to an object (control the execution order by calling super methods), which is more flexible than generating subclasses.

1. decorator mode application scenario

Java IO streams, the caching framework of Mybatis, sessions in Spring, and so on.

2. advantages and disadvantages of decorator mode

Advantages: the function can be dynamically extended without changing the original object, and multiple extended functions can be executed in the desired order to achieve different effects.

Disadvantages: more classes, making the program complex

3. decorator mode definition

(1) Abstract component: defines an abstract interface (or abstract class) to specify the classes that prepare additional functions

(2) Concrete component: the class to be attached with functions, which implements the role interface of abstract components

(3) Abstract decorator: holds references to specific component roles and defines interfaces consistent with abstract component roles

(4) Concrete decoration: it implements the role of abstract decorator and is responsible for adding additional functions to specific components.

After finishing the characteristics of decorators, I will write a case here to help you understand how to use the decorator model in actual projects

Case: expand new functions on the basis of the original gateway functions

Demand analysis: the original function of the gateway interface is mainly to parse data and desensitize some data. With the development of business, it is now necessary to expand new functions on the basis of the original functions, including the current limiting operation of the interface and the collection of interface logs

Through the transformation of decorator mode, the changes of class diagram are as follows

 

Code implementation part

1. define an abstract class (original code)

package com.brian.decorative.service;

/**
 * @program: architect
 * @author: Brian Huang
 * @create: 2019-05-14 21:08
 **/
public abstract class BaseGateway {

    public abstract void service();
}

2. define the decorated role (original code)

package com.brian.decorative.service.impl;

import com.brian.decorative.service.BaseGateway;
import lombok.extern.slf4j.Slf4j;

/**
 * @program: architect
 * @author: Brian Huang
 * @create: 2019-05-14 21:15
 **/
@Slf4j
public class DesensitizationComponent  extends BaseGateway {

    @Override
    public void service() {
        log.info("1-->>> Get basic operations in the gateway,Data desensitization...");
    }
}

3. define abstract decorative roles (extended code)

package com.brian.decorative.service;

/**
 * @program: architect
 * @author: Brian Huang
 * @create: 2019-05-14 21:13
 **/
public abstract class GatewayDecorate extends BaseGateway {

    private BaseGateway baseGateway;

    public GatewayDecorate(BaseGateway baseGateway) {
        this.baseGateway = baseGateway;
    }

    @Override
    public void service() {
        if(baseGateway !=null){
            baseGateway.service();
        }
    }
}

4. define specific decorative roles (extended codes)

package com.brian.decorative.service.impl;

import com.brian.decorative.service.BaseGateway;
import com.brian.decorative.service.GatewayDecorate;
import lombok.extern.slf4j.Slf4j;

/**
 * @program: architect
 * @author: Brian Huang
 * @create: 2019-05-14 21:16
 **/
@Slf4j
public class LimitComponent extends GatewayDecorate {

    public LimitComponent(BaseGateway baseGateway) {
        super(baseGateway);
    }

    @Override
    public void service() {
        super.service();
        log.info("3-->>> New in gateway API Current limiting of interface..");
    }
}



----------


package com.brian.decorative.service.impl;

import com.brian.decorative.service.BaseGateway;
import com.brian.decorative.service.GatewayDecorate;
import lombok.extern.slf4j.Slf4j;

/**
 * @program: architect
 * @author: Brian Huang
 * @create: 2019-05-14 21:16
 **/
@Slf4j
public class LogComponent  extends GatewayDecorate {

    public LogComponent(BaseGateway baseGateway) {
        super(baseGateway);
    }

    @Override
    public void service() {
        super.service();
        log.info("2-->>> Add log collection in gateway..");
    }
}

5. use factory to obtain decoration class (extended code)

package com.brian.decorative.factory;

import com.brian.decorative.service.BaseGateway;
import com.brian.decorative.service.impl.DesensitizationComponent;
import com.brian.decorative.service.impl.LimitComponent;
import com.brian.decorative.service.impl.LogComponent;

/**
 * @program: architect
 * @author: Brian Huang
 * @create: 2019-05-14 21:38
 **/
public class FactoryGateway {

    public static BaseGateway getBaseGateway() {
        return new LimitComponent(new LogComponent(new DesensitizationComponent()));
    }


    public static void main(String[] args) {
        FactoryGateway.getBaseGateway().service();
    }
}

Test results:

Difference between responsibility chain and decoration mode:
1. in the responsibility chain mode, each callee holds the reference of the next callee. The client only needs to initiate a call. The whole process is a chain call, executed from front to back.
2. in the decorator mode, the decorator holds the decorated object and has the behavior of the decorator to supplement and enhance its behavior. The whole process is like a wrapped onion, which is called from the inner layer to the outer layer.

Difference between decorator and adapter:
In fact, the adapter pattern is also a Wrapper pattern. They all seem to wrap a class or object, but they are used for very different purposes:
1. The meaning of the adapter pattern is to change an interface into another interface. Its purpose is to achieve the purpose of reuse by changing the interface
2. The decorator mode should not change the interface of the decorated object, but just keep the original excuse, but enhance the function of the original interface, or change the processing method of meta objects to improve the performance

 

Blog reference: https://www.cnblogs.com/xrq730/p/4908940.html

Tags: Programming

Posted by dips_007 on Tue, 31 May 2022 15:47:37 +0530