前言
大家好,我是练习两年半的Java练习生,最近阅读了《深入浅出设计模式(中文版)》,学习了各种设计模式,所以想出一个专栏和大家分享一下!
如果大家觉得文章还可以,欢迎关注点赞!后续还会陆续更新!!
一、定义
允许你将对象组成树形结构来表现“整体/部分”的层次结构。组合能让客户以一致的方式处理个别对象和对象组合。
二、类图
三、应用
3.1 需求
假设我们要设计一个菜单系统,其中包括一系列的菜单项和子菜单。菜单项和子菜单都可以被点击,但是子菜单本身也可以包含一系列的菜单项和子菜单。为了实现这个系统,我们可以使用组合模式来管理菜单项和子菜单。
3.2 分析
首先,我们定义一个菜单项的接口 MenuItem,它包含了两个方法 getName() 和 click(),分别用于获取菜单项名称和执行菜单项操作。然后,我们定义一个子菜单接口 Menu,它继承了菜单项接口,并增加了以下方法:
- add(MenuItem item):添加菜单项或子菜单到当前菜单。
- remove(MenuItem item):从当前菜单中移除指定的菜单项或子菜单。
- getChild(int index):获取当前菜单的指定位置的菜单项或子菜单。
3.3 实现
接着,我们实现菜单项接口的具体类 MenuItemImpl,它包含了菜单项的名称和点击操作。
public class MenuItemImpl implements MenuItem {
private String name;
public MenuItemImpl(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void click() {
System.out.println("Clicked " + name);
}
}
接下来,我们实现子菜单接口的具体类 MenuImpl,它包含了一个菜单项和一个子菜单的列表,以及菜单的名称。
import java.util.ArrayList;
import java.util.List;
public class MenuImpl implements Menu {
private List<MenuItem> menuItems;
private List<Menu> subMenus;
private String name;
public MenuImpl(String name) {
this.name = name;
this.menuItems = new ArrayList<>();
this.subMenus = new ArrayList<>();
}
public String getName() {
return name;
}
public void click() {
System.out.println("Clicked " + name);
}
public void add(MenuItem item) {
menuItems.add(item);
}
public void add(Menu menu) {
subMenus.add(menu);
}
public void remove(MenuItem item) {
menuItems.remove(item);
}
public void remove(Menu menu) {
subMenus.remove(menu);
}
public MenuItem getChild(int index) {
if (index < menuItems.size()) {
return menuItems.get(index);
} else {
return subMenus.get(index - menuItems.size());
}
}
}
public class Client {
public static void main(String[] args) {
MenuItem item1 = new MenuItemImpl("Item 1");
MenuItem item2 = new MenuItemImpl("Item 2");
Menu subMenu1 = new MenuImpl("Sub Menu 1");
subMenu1.add(new MenuItemImpl("Sub Item 1"));
subMenu1.add(new MenuItemImpl("Sub Item 2"));
Menu subMenu2 = new MenuImpl("Sub Menu 2");
subMenu2.add(subMenu1);
}
}
四、问题
五、总结
以上就是今天要讲的内容,本文介绍了设计模式中组合模式,该模式要注意叶子节点和子节点要继承于同一个类,并统一对待。