Java 组合模式
2022-02-10 本文已影响0人
CodeDuan
Java 组合模式
一、定义
组合模式又名部分整体模式,是用于把一组相似的对象当作一个单一的对象,组合模式依据树形结构来组合对象,用来表示部分以及整体层次,这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。
主要角色:
抽象根节点:定义系统各层次对象共有的方法和属性,可以预先定义一些默认行为和属性。
树枝节点:定义树枝节点的行为,存储子节点,组合树枝节点和叶子节点形成一个树形结构。
叶子节点:叶子节点对象,其下无分支,是系统遍历的最小单位。
二、代码实现
举例:在文件管理系统中,常常有根目录和子目录,子目录中又包含着文件和子目录,或者说子目录中包含子目录又包含着文件,如下图所示,这就是一个树型结构。
tree.png抽象根节点(菜单组件)
public abstract class MenuComponent {
//菜单名
protected String name;
//菜单层级
protected int level;
//添加子菜单
public void add(MenuComponent menuComponent){
throw new UnsupportedOperationException();
}
//移除子菜单
public void remove(MenuComponent menuComponent){
throw new UnsupportedOperationException();
}
//获取指定的子菜单
public MenuComponent getChild(int index){
throw new UnsupportedOperationException();
}
//获取菜单名称
public String getName(){
return name;
}
//打印菜单名称(子菜单或菜单项)
public abstract void print();
}
树枝节点(菜单)
public class Menu extends MenuComponent{
//存储菜单或者菜单项
private List<MenuComponent> menuComponentList = new ArrayList<>();
public Menu(String name,int level){
this.name = name;
this.level = level;
}
@Override
public void add(MenuComponent menuComponent) {
menuComponentList.add(menuComponent);
}
@Override
public void remove(MenuComponent menuComponent) {
menuComponentList.remove(menuComponent);
}
@Override
public MenuComponent getChild(int index) {
return menuComponentList.get(index);
}
@Override
public void print() {
//打印菜单名称
for (int i=0;i<level;i++){
System.out.print("-");
}
System.out.println(name);
for (MenuComponent component:menuComponentList){
component.print();
}
}
}
叶子节点(菜单项)
public class MenuItem extends MenuComponent{
public MenuItem(String name,int level){
this.name = name;
this.level = level;
}
@Override
public void print() {
for (int i=0;i<level;i++){
System.out.print("-");
}
System.out.println(name);
}
}
使用:
public static void main(String[] args) {
//创建根目录
MenuComponent menuComponent = new Menu("根目录",1);
//添加两个子菜单项
menuComponent.add(new MenuItem("英雄联盟",2));
menuComponent.add(new MenuItem("地下城",2));
//创建二级目录
MenuComponent menu1 = new Menu("办公",2);
menu1.add(new MenuItem("微信",3));
menu1.add(new Menu("QQ",3));
//将二级目录添加至根目录
menuComponent.add(menu1);
menuComponent.print();
}
输出:
-根目录
--英雄联盟
--地下城
--办公
---微信
---QQ
由此输出的目录结构如图所示:
tree2.png三、总结
组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,让客户端忽略了层次的差异,方便对整个层次结构进行控制。
客户端可以一致地使用一个组合结构或其中单个对象,不必关心处理的单个对象还是整个组合结构,简化了客户端代码。
组合模式中增加新树枝节点或者叶子节点都很方便,无需修改现有类,符合开闭原则。
组合模式为树形结构的面向对象实现提供了一种灵活的解决方案,通过叶子节点和树枝节点的递归组合可以形成复杂的树形结构,对树形结构的控制非常简单。
所以组合模式的应用场景就是出现在树形结构的地方,比如文件目录,多级目录等呈现树形结构的程序。