组合模式
组合模式(Composite Pattern)也叫合成模式,有时又叫做部分-整体模式(Part-Whole),主要是用来描述部分与整体的关系,其定义如下: Compose objects into tree structures to represent part-whole hierarchies.Composite lets clients treat individual objects and compositions of objects uniformly.(将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。)
基本上来说,只要是树形结构,就要考虑使用组合模式。比如我们常用的无限级菜单,公司-部门-用户这样的结构,都可以选择组合模式。
比如菜单为例:
菜单PO:
@Data
public class Menu implements Serializable {
/**
* 菜单id
*/
@TableId(type = IdType.AUTO)
private Integer id;
/**
* 菜单名称
*/
private String name;
/**
* 菜单路由(路径)
*/
private String path;
/**
* 菜单图标
*/
private String icon;
/**
* 菜单父级id
*/
private Integer parentId;
}
菜单VO:
@Data
public class MenuTreeVo {
/**
* 菜单id
*/
private Integer id;
/**
* 菜单名称
*/
private String name;
/**
* 菜单路由(路径)
*/
private String path;
/**
* 菜单图标
*/
private String icon;
/**
* 菜单父级id
*/
private Integer parentId;
/**
* 子菜单
*/
private List<MenuTreeVo> children = new ArrayList<>();
}
这时候我们需要把数据库查询的结果返回成树状图形式
public static List<MenuTreeVo> convertToTreeVo(List<Menu> list) {
if (list.size() == 0) {
return new ArrayList<>();
}
List<MenuTreeVo> treeVoList = new ArrayList<>();
instance = new ModelMapper();
Map<Integer, MenuTreeVo> treeMap = list.stream().collect(Collectors.toMap(Menu::getId, menu -> instance.map(menu, MenuTreeVo.class)));
treeMap.entrySet().forEach(entry -> {
MenuTreeVo treeVo = entry.getValue();
if (treeVo.getParentId() == 0) {
treeVoList.add(treeVo);
} else {
treeMap.get(treeVo.getParentId()).getChildren().add(treeVo);
}
});
return treeVoList;
}
先将数据库查询List,转化成Map,然后通过key和对象绑定,快速生成树状图,时间复杂度为O(2n)。