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