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

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


相关文章
|
7月前
|
设计模式 Java 定位技术
【设计模式】【结构型模式】组合模式(Composite)
一、入门 什么是组合模式 组合模式(Composite Pattern)是一种结构型设计模式,它允许你将对象组合成树形结构来表示“部分-整体”的层次关系。组合模式使得客户端可以统一处理单个对象和组合对
222 10
|
7月前
|
设计模式 XML JSON
【设计模式】【行为型模式】访问者模式(Visitor)
一、入门 什么是访问者模式? 访问者模式(Visitor Pattern)是一种行为设计模式,允许你将算法与对象结构分离。通过这种方式,可以在不改变对象结构的情况下,向对象结构中的元素添加新的操作。
225 10
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
设计模式 JavaScript 前端开发
JavaScript设计模式--访问者模式
【10月更文挑战第1天】
300 124
|
10月前
|
设计模式 存储 安全
「全网最细 + 实战源码案例」设计模式——组合模式
组合模式(Composite Pattern)是一种结构型设计模式,用于将对象组合成树形结构以表示“部分-整体”的层次结构。它允许客户端以一致的方式对待单个对象和对象集合,简化了复杂结构的处理。组合模式包含三个主要组件:抽象组件(Component)、叶子节点(Leaf)和组合节点(Composite)。通过这种模式,客户端可以统一处理简单元素和复杂元素,而无需关心其内部结构。适用于需要实现树状对象结构或希望以相同方式处理简单和复杂元素的场景。优点包括支持树形结构、透明性和遵循开闭原则;缺点是可能引入不必要的复杂性和过度抽象。
294 22
|
设计模式 Java
Java中的设计模式及其应用场景解析
Java中的设计模式及其应用场景解析
|
10月前
|
设计模式 算法 Java
【再谈设计模式】访问者模式~操作对象结构的新视角
  访问者模式是一种行为设计模式,旨在解决对象结构与操作逻辑的耦合问题。在软件系统开发中,当面临复杂的对象结构(如多种类型对象组成的树形或图形结构),且需要对这些对象执行不同操作时,传统方式将操作直接写在对象类中会导致类职责过多,不利于维护和扩展。而访问者模式通过将操作与对象结构分离,允许在不改变现有对象结构的情况下定义新操作,元素接受访问者访问,访问者定义对不同类型元素的操作逻辑,从而为应对这种复杂情况提供了有效的解决方案。
191 0
|
设计模式 Java
Java设计模式:组合模式的介绍及代码演示
组合模式是一种结构型设计模式,用于将多个对象组织成树形结构,并统一处理所有对象。例如,统计公司总人数时,可先统计各部门人数再求和。该模式包括一个通用接口、表示节点的类及其实现类。通过树形结构和节点的通用方法,组合模式使程序更易扩展和维护。
204 2
Java设计模式:组合模式的介绍及代码演示
|
设计模式 存储 安全
Java设计模式-组合模式(13)
Java设计模式-组合模式(13)
154 2
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP的编程实践中,设计模式是解决常见软件设计问题的最佳实践。单例模式作为设计模式中的一种,确保一个类只有一个实例,并提供全局访问点,广泛应用于配置管理、日志记录和测试框架等场景。本文将深入探讨单例模式的原理、实现方式及其在PHP中的应用,帮助开发者更好地理解和运用这一设计模式。
在PHP开发中,单例模式通过确保类仅有一个实例并提供一个全局访问点,有效管理和访问共享资源。本文详细介绍了单例模式的概念、PHP实现方式及应用场景,并通过具体代码示例展示如何在PHP中实现单例模式以及如何在实际项目中正确使用它来优化代码结构和性能。
213 2

热门文章

最新文章