【设计模式】【第八章】【商品多级分类目录场景】【组合模式+访问者模式】

简介: 创建design-demo项目创建ItemController创建ItemService创建ItemServiceimpl创建ItemVisitor创建DelItemVisitor创建AddItemVisitor创建ProductItem创建AbstractProductItem创建MockDb

文章目录


创建design-demo项目

创建ItemController

创建ItemService

创建ItemServiceimpl

创建ItemVisitor

创建DelItemVisitor

创建AddItemVisitor

创建ProductItem

创建AbstractProductItem

创建MockDb


创建design-demo项目


项目代码:https://gitee.com/java_wxid/java_wxid/tree/master/demo/design-demo


项目结构如下(示例):


3bcb62ab38264dbcb5de994b58ea1083.png


创建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);
    }
}


相关文章
|
14天前
|
设计模式 JavaScript 前端开发
js设计模式【详解】—— 组合模式
js设计模式【详解】—— 组合模式
25 7
|
2月前
|
设计模式 算法 Java
【设计模式】JAVA Design Patterns——Acyclic Visitor(非循环访问者模式)
【设计模式】JAVA Design Patterns——Acyclic Visitor(非循环访问者模式)
|
19天前
|
设计模式 存储 安全
Java设计模式:组合模式之透明与安全的两种实现(七)
Java设计模式:组合模式之透明与安全的两种实现(七)
|
19天前
|
设计模式 Java
Java设计模式之组合模式详解
Java设计模式之组合模式详解
|
20天前
|
设计模式
组合模式-大话设计模式
组合模式-大话设计模式
6 0
|
2月前
|
设计模式 消息中间件 存储
18个并发场景的设计模式详解,有没有你的盲区
这些模式在多线程并发编程中非常有用`。在分布式应用中,并发场景无处不在,理解和掌握这些并发模式的编码技巧,有助于我们在开发中解决很多问题,这要把这些与23种设计模式混淆了,虽然像单例模式是同一个,但这个是考虑并发场景下的应用。内容比较多,V哥建议可以收藏起来,即用好查。拜拜了您誒,晚安。
18个并发场景的设计模式详解,有没有你的盲区
|
2月前
|
设计模式 安全 Java
【设计模式】字节三面:请举例阐释访问者模式
【设计模式】字节三面:请举例阐释访问者模式
20 2
|
2月前
|
设计模式 安全 Java
[设计模式Java实现附plantuml源码~结构型]树形结构的处理——组合模式
[设计模式Java实现附plantuml源码~结构型]树形结构的处理——组合模式
|
2月前
|
设计模式 Java
【设计模式】文件目录管理是组合模式吗?
【设计模式】文件目录管理是组合模式吗?
21 0
|
6天前
|
设计模式 Go
Go语言设计模式:使用Option模式简化类的初始化
在Go语言中,面对构造函数参数过多导致的复杂性问题,可以采用Option模式。Option模式通过函数选项提供灵活的配置,增强了构造函数的可读性和可扩展性。以`Foo`为例,通过定义如`WithName`、`WithAge`、`WithDB`等设置器函数,调用者可以选择性地传递所需参数,避免了记忆参数顺序和类型。这种模式提升了代码的维护性和灵活性,特别是在处理多配置场景时。
41 8