商品多级分类目录场景组合模式+访问者模式

Posted 我是廖志伟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了商品多级分类目录场景组合模式+访问者模式相关的知识,希望对你有一定的参考价值。

文章目录

创建design-demo项目

项目代码:https://gitee.com/java_wxid/java_wxid/tree/master/demo/design-demo
项目结构如下(示例):

创建ItemController

代码如下(示例):

package com.example.designdemo.controller;

import com.example.designdemo.items.node.ProductItem;
import com.example.designdemo.service.ItemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
/**
 * @Author: zhiwei Liao
 * @Date: 2022/9/29 21:29
 * @Description:
 */
@RestController
public class ItemController 
    @Autowired
    private ItemService itemService;

    @GetMapping("get")
    public ProductItem getItem() 
        return itemService.getItem();
    

    @PostMapping("del")
    public ProductItem delItem(@RequestBody ProductItem productItem) 
        return itemService.delItem(productItem);
    

    @PostMapping("add")
    public ProductItem addItem(@RequestBody ProductItem productItem) 
        return itemService.addItem(productItem);
    



创建ItemService

代码如下(示例):

package com.example.designdemo.service;

import com.example.designdemo.items.node.ProductItem;

/**
 * @Author: zhiwei Liao
 * @Date: 2022/9/29 21:29
 * @Description:
 */
public interface ItemService 

    ProductItem getItem();

    ProductItem delItem(ProductItem productItem);

    ProductItem addItem(ProductItem productItem);



创建ItemServiceimpl

代码如下(示例):

package com.example.designdemo.service.impl;

import com.example.designdemo.MockDb;
import com.example.designdemo.items.node.ProductItem;
import com.example.designdemo.items.visitor.AddItemVisitor;
import com.example.designdemo.items.visitor.DelItemVisitor;
import com.example.designdemo.service.ItemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
 * @Author: zhiwei Liao
 * @Date: 2022/9/29 21:29
 * @Description:
 */
@Service
public class ItemServiceimpl implements ItemService 
    @Autowired
    private DelItemVisitor delItemVisitor;

    @Autowired
    private AddItemVisitor addItemVisitor;

    //这部分只有初始化的时候获取一次 或者 直接预热到缓存中
    public ProductItem getItem() 
        System.out.println("从DB 获取所有的目录");
        System.out.println("将数据组装为 ProductItem");
        System.out.println("将组装好的 ProductItem 放入缓存中,永不过期 ");
        return MockDb.ProductItem;
    

    public ProductItem delItem(ProductItem productItem) 
        ProductItem item = delItemVisitor.visitor(productItem);
        MockDb.ProductItem = item;
        System.out.println("update db");
        return item;
    

    public ProductItem addItem(ProductItem productItem) 
        ProductItem item = addItemVisitor.visitor(productItem);
        MockDb.ProductItem = item;
        System.out.println("update db");
        return item;
    


创建ItemVisitor

代码如下(示例):

package com.example.designdemo.items.visitor;


import com.example.designdemo.items.node.ProductItem;
/**
 * @Author: zhiwei Liao
 * @Date: 2022/9/29 21:29
 * @Description:
 */
public interface ItemVisitor<T> 
    T visitor(ProductItem productItem);


创建DelItemVisitor

代码如下(示例):

package com.example.designdemo.items.visitor;

import com.example.designdemo.MockDb;
import com.example.designdemo.items.node.ProductItem;
import org.springframework.stereotype.Component;
/**
 * @Author: zhiwei Liao
 * @Date: 2022/9/29 21:29
 * @Description:
 */
@Component
public class DelItemVisitor implements ItemVisitor<ProductItem>
    // 入参是 id 2, pid为 1
    @Override
    public ProductItem visitor(ProductItem productItem) 
        ProductItem currentItem = MockDb.ProductItem; //  从缓存来的 to do
        if(productItem.getId() == currentItem.getId()) 
            throw new UnsupportedOperationException("根节点不能删。");
        
        if(productItem.getPid() == currentItem.getId()) 
            currentItem.removeChild(productItem);
            return currentItem;
        
        delChild(productItem, currentItem);
        return currentItem;
    

    private void delChild(ProductItem productItem, ProductItem currentItem) 
        for(ProductItem item : currentItem.getChild()) 
            if(item.getId() == productItem.getPid()) 
                item.removeChild(productItem);
                break;
             else 
                delChild(productItem, item);
            
        
    


创建AddItemVisitor

代码如下(示例):

package com.example.designdemo.items.visitor;

import com.example.designdemo.MockDb;
import com.example.designdemo.items.node.ProductItem;
import org.springframework.stereotype.Component;
/**
 * @Author: zhiwei Liao
 * @Date: 2022/9/29 21:29
 * @Description:
 */
@Component
public class AddItemVisitor implements ItemVisitor<ProductItem>
    // 入参是 id 2, pid为 1
    @Override
    public ProductItem visitor(ProductItem productItem) 
        ProductItem currentItem = MockDb.ProductItem; //  从缓存来的 to do
        if(productItem.getId() == currentItem.getId()) 
            throw new UnsupportedOperationException("根节点是唯一的。");
        
        if(productItem.getPid() == currentItem.getId()) 
            currentItem.addChild(productItem);
            return currentItem;
        
        addChild(productItem, currentItem);
        return currentItem;
    

    private void addChild(ProductItem productItem, ProductItem currentItem) 
        for(ProductItem item : currentItem.getChild()) 
            if(item.getId() == productItem.getPid()) 
                item.addChild(productItem);
                break;
             else 
                addChild(productItem, item);
            
        
    


创建ProductItem

代码如下(示例):

package com.example.designdemo.items.node;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
 * @Author: zhiwei Liao
 * @Date: 2022/9/29 21:29
 * @Description:
 */
public class ProductItem extends AbstractProductItem
    private int id;
    private int pid;
    private String name;
    private List<ProductItem> child = new ArrayList<>();

    @Override
    public void removeChild(AbstractProductItem item) 
        ProductItem removeItem = (ProductItem) item;
        this.child = child.stream().filter(x->x.getId() != removeItem.getId()).collect(Collectors.toList());
    

    @Override
    public void addChild(AbstractProductItem item) 
        this.child.add((ProductItem) item);
    

    public int getId() 
        return id;
    

    public void setId(int id) 
        this.id = id;
    

    public int getPid() 
        return pid;
    

    public void setPid(int pid) 
        this.pid = pid;
    

    public String getName() 
        return name;
    

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

    public List<ProductItem> getChild() 
        return child;
    

    public void setChild(List<ProductItem> child) 
        this.child = child;
    


创建AbstractProductItem

代码如下(示例):

package com.example.designdemo.items.node;
/**
 * @Author: zhiwei Liao
 * @Date: 2022/9/29 21:29
 * @Description:
 */
public abstract class AbstractProductItem 
    public abstract void removeChild(AbstractProductItem item);
    public abstract void addChild(AbstractProductItem item);


创建MockDb

代码如下(示例):

package com.example.designdemo;


import com.example.designdemo.items.node.ProductItem;

import java.util.ArrayList;
import java.util.List;
/**
 * @Author: zhiwei Liao
 * @Date: 2022/9/29 21:29
 * @Description:
 */
public class MockDb 
    public static com.example.designdemo.items.node.ProductItem ProductItem = new ProductItem();
    static 
        ProductItem.setId(1);
        ProductItem.setPid(0);
        ProductItem.setName("书籍");
        List<ProductItem> child = new ArrayList<>();
        ProductItem c1 = new ProductItem();
        c1.setId(2);
        c1.setPid(1);
        c1.setName("技术书籍");
        ProductItem c2 = new ProductItem();
        c2.setId(3);
        c2.setPid(1);
        c2.setName("历史书籍");
        List<ProductItem> child1 = new ArrayList<>();
        ProductItem c3 = new ProductItem();
        c3.setId(4);
        c3.setPid(2);
        c3.setName("并发编程");
        ProductItem c4 = new ProductItem();
        c4.setId(5);
        c4.setPid(2);
        c4.setName("JVM");
        child1.add(c3);
        child1.add(c4);
        c1.setChild(child1);
        child.add(c1);
        child.add(c2);
        ProductItem.setChild(child);
    


以上是关于商品多级分类目录场景组合模式+访问者模式的主要内容,如果未能解决你的问题,请参考以下文章

商品多级分类目录场景组合模式+访问者模式

设计模式组合模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

桥接模式

使用多级分组报表展现分类数据

多级伸缩菜单——组合模式

设计模式分类