Use the decorator pattern in springboot

What is the decorator pattern

Decorator Pattern (Decorator Pattern) is a structural design pattern that allows adding new functionality to an existing object without changing its structure. It acts as a wrapper around an existing class.

Intent: To dynamically add some additional responsibilities to an object. The decorator pattern is more flexible than subclassing in terms of adding functionality.

Usage scenarios: 1. Extend the function of a class. 2. Add functions dynamically and cancel them dynamically.

Note: Inheritance can be replaced.

Decorator pattern, it's you and you

Link: Decorator pattern .

Decorator pattern, it's you and you

insert image description here

The decorator pattern is often seen in java's IO stream

BufferedInputStream is the same as BufferedOutputStream, they are all specific decoration classes in decorator mode.
Used to decorate InputStream and other specific implementation classes under OutputStream, such as FileInputStream
insert image description here

Enhance ArrayList through decorator mode to realize building tree structure collection

Link: Java collections are built into tree collections TreeUtil .

package com.zm.decorator;

import java.util.List;

/**
 * 树形结构基础类
 * @param <T>
 */
public interface BaseTree<T> {
    
    

    String getId();

    void setId(String id);

    String getPid();

    void setPid(String pid);

    List<T> getChildren();

    void setChildren(List<T> children);
}

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 树形结构工具类
 *  T 实现了BaseTree接口的实体对象,实体对象中默认有表示父子关系的id和pid
 *  N id和pid的类型
 *  由于 实体对象中表示父子关系的属性名称不一定是id和pid,所以提供了getId和getPid方法进行拓展
 */
public abstract class TreeUtil<T extends BaseTree<T>, N> {
    
    

    /**
     * id的get方法
     *
     * @param t 对象
     * @return id 的值
     */
    protected abstract N getId(T t);

    /**
     * 父级id的get方法
     *
     * @param t 对象
     * @return pid 的值
     */
    protected abstract N getPid(T t);

    /**
     * 格式化成树形结构
     * 要点:非基本类型的变量存储的是内存地址,对它的操作会影响到原始值。
     *
     * @param list 要操作的列表
     * @return 树形结果列表
     */
    public List<T> parseTree(List<T> list) {
    
    
        if(list.isEmpty()){
    
    
            return list;
        }
        List<T> resultList = new ArrayList<>();
        // 知道有多少个元素,那么在创建的时候直接指定长度,避免因扩容而浪费时间
        Map<N, T> tmpMap = new HashMap<>(list.size());
        for (T t : list) {
    
    
            tmpMap.put(this.getId(t), t);
        }
        for (T t : list) {
    
    
              /*1、tmpMap存储的是以id为key的键值对。
               2、如果以pid为key可以从tmpMap中取出对象,则说明该元素是子级元素。
               3、如果以pid为key不能从tmpMap中取出对象,则说明该元素是最上层元素。
               4、子级元素放在父级元素的children中。
               5、最上层元素添加到结果中
               */
            T tmap = tmpMap.get(this.getPid(t));
            if (tmap != null) {
    
    
                if (null == tmap.getChildren()) {
    
    
                    tmap.setChildren(new ArrayList<>());
                }
                tmap.getChildren().add(t);
            } else {
    
    
                resultList.add(t);
            }
        }
        // 如果集合中存储了大量的元素,并且集合已经使用完毕,那么尽量调用clear方法来及时的释放空间。
        // 如果集合不会重复使用,那么将集合也设置为null将内存一并释放。这样有助于gc能更快完成清除内存的工作。
        list.clear();
        list = null;
        return resultList;
    }
}
package com.zm.decorator;

import java.util.List;

public class TestNode implements BaseTree<TestNode>{
    
    

    private List<TestNode> children;

    private String id;

    private String pid;

    private String name;

    @Override
    public List<TestNode> getChildren() {
    
    
        return children;
    }

    @Override
    public void setChildren(List<TestNode> children) {
    
    
        this.children = children;
    }

    @Override
    public String getId() {
    
    
        return id;
    }

    @Override
    public void setId(String id) {
    
    
        this.id = id;
    }

    @Override
    public String getPid() {
    
    
        return pid;
    }

    @Override
    public void setPid(String pid) {
    
    
        this.pid = pid;
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }
}

package com.zm.decorator;

import java.util.ArrayList;
import java.util.List;

/**
 * 使用装饰者模式对ArrayList进行构建树形功能进行增强
 * @author zhou
 */
public class MyTreeList<E extends BaseTree<E>> extends ArrayList<E>{
    
    

    protected ArrayList<E> list;

    public MyTreeList(ArrayList<E> list){
    
    
        this.list = list;
    }

    public List<E> tree(){
    
    
        TreeUtil<E, String> treeUtil = new TreeUtil<E, String>() {
    
    
            @Override
            protected String getId(E e) {
    
    
                return e.getId();
            }

            @Override
            protected String getPid(E e) {
    
    
                return e.getPid();
            }
        };
        return treeUtil.parseTree(list);
    }


    public static void main(String[] args) {
    
    
        ArrayList<TestNode> objects = getTestNodes();
        test2(objects);
    }

    private static void test2(ArrayList<TestNode> objects) {
    
    
        MyTreeList<TestNode> testNodes = new MyTreeList<>(objects);
        List<TestNode> tree = testNodes.tree();
        System.out.println(tree);
    }

    private static ArrayList<TestNode> getTestNodes() {
    
    
        TestNode testNode1 = new TestNode();
        testNode1.setName("中国");
        testNode1.setId("0");

        TestNode testNode2 = new TestNode();
        testNode2.setName("福建省");
        testNode2.setId("1");
        testNode2.setPid("0");

        TestNode testNode3 = new TestNode();
        testNode3.setName("浙江省");
        testNode3.setId("2");
        testNode3.setPid("0");

        TestNode testNode4 = new TestNode();
        testNode4.setName("福州市");
        testNode4.setId("3");
        testNode4.setPid("1");


        TestNode testNode5 = new TestNode();
        testNode5.setName("宁德市");
        testNode5.setId("4");
        testNode5.setPid("1");


        ArrayList<TestNode> objects = new ArrayList<>();
        objects.add(testNode1);
        objects.add(testNode2);
        objects.add(testNode3);
        objects.add(testNode4);
        objects.add(testNode5);
        return objects;
    }


}

insert image description here

The interface implementation class in the project is enhanced with decorator mode

Calculate order amount


/**
 * 订单金额计算
 */
public interface OrderCalculationService {
    
    

    String orderCalculation();

}
import org.springframework.stereotype.Service;

@Service("OrderCalculationServiceImpl")
public class OrderCalculationServiceImpl implements OrderCalculationService{
    
    

    @Override
    public String orderCalculation() {
    
    
        return "订单计算价格为50元";
    }
}

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @author zhou
 */
@RestController
public class DecoratorController {
    
    

    @Resource(name="OrderCalculationServiceImpl")
    OrderCalculationService orderCalculationService1;

 
    @GetMapping("order1")
    public String test(){
    
    
        String s = orderCalculationService1.orderCalculation();
        System.out.println(s);
        return s;
    }

}

Enhance the random deduction amount function

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service("OrderCalculationReductionImpl")
public class OrderCalculationReductionImpl extends OrderCalculationServiceImpl {
    
    

    private final OrderCalculationServiceImpl orderCalculationService;

    public OrderCalculationReductionImpl(@Qualifier("OrderCalculationServiceImpl") OrderCalculationServiceImpl orderCalculationService) {
    
    
        this.orderCalculationService = orderCalculationService;
    }

    public String reduction() {
    
    
        // 不改动之前的逻辑 进行功能增强 也可随时取消
        String s = orderCalculationService.orderCalculation();
        s = "原先:" + s + ",随机减免后,订单计算价格为49.9元";
        return s;
    }

}

package com.zm.decorator;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @author zhou
 */
@RestController
public class DecoratorController {
    
    

    @Resource(name="OrderCalculationServiceImpl")
    OrderCalculationService orderCalculationService1;

    @Resource
    OrderCalculationReductionImpl orderCalculationReduction;

    @GetMapping("order1")
    public String test(){
    
    
        String s = orderCalculationService1.orderCalculation();
        System.out.println(s);
        return s;
    }

    @GetMapping("order2")
    public String test2(){
    
    
        // 现在需要新增 随机减免功能
        String s = orderCalculationReduction.reduction();
        System.out.println(s);
        return s;
    }
}

Guess you like

Origin blog.csdn.net/qq_41604890/article/details/123035937