目录
一、基础概念
二、UML类图
三、角色设计
四、案例分析
1、基本实现
2、菜单遍历
五、总结
组合模式(Composite Pattern)又叫部分-整体模式,它通过将对象组合成树形结构来表示“整体-部分”的层次关系,允许用户统一单个对象和组合对象的处理逻辑。
角色 | 描述 |
---|---|
抽象构件角色 | 定义参与组合对象的共有方法和属性,可以是接口或抽象类 |
叶构件角色 | 基本构件类,无子构件,实现抽象构件角色所定义的接口 |
容器构件角色 | 存储子构件,实现子构件的相关操作,定义子构件的添加、删除等方法 |
客户端 | 通过抽象组件操作组合部件的对象 |
抽象构件:
public abstract class Component {
public void addComponent(Component component){
}
public void remove(Component component){
}
public Component getComponent(int i){
return null;
}
public abstract void operation();
}
叶子构件:
public class Leaf extends Component{
@Override
public void operation() {
}
}
容器构件:
import java.util.ArrayList;
import java.util.List;
public class Composite extends Component{
private List componentList = new ArrayList<>();
@Override
public void addComponent(Component component) {
componentList.add(component);
}
@Override
public void remove(Component component) {
componentList.remove(component);
}
@Override
public Component getComponent(int i) {
return componentList.get(i);
}
@Override
public void operation() {
for(Component component : componentList){
component.operation();
}
}
}
客户端:
public class Client {
public static void main(String[] args) {
Component leaf1 = new Leaf();
Component leaf2 = new Leaf();
Composite composite1 = new Composite();
composite1.addComponent(leaf1);
composite1.addComponent(leaf2);
Component leaf3 = new Leaf();
Component leaf4 = new Leaf();
Composite composite2 = new Composite();
composite2.addComponent(leaf3);
composite2.addComponent(leaf4);
composite2.addComponent(composite1);
composite2.operation();
}
}
创建了两个叶节点leaf1和leaf2,一个复合组件composite1,组合包含leaf1和leaf2。
创建了两个叶节点leaf3和leaf4,一个复合组件composite2,组合包含leaf3、leaf4以及复合组件composite1。
调用composite2的operation方法,会遍历其下的所有子组件并调用其operation方法。
综上,这段基础代码演示了通过组合模式将对象组合成树状层次结构,通过调用根节点操作使得递归调用所有子节点的操作,实现统一处理个别对象和组合对象的情形,以达到“合成复用原则”。
我们平时用到的管理系统肯定会有1级菜单,2级菜单,3级菜单甚至4级菜单等等,下面就举一个更形象的例子来实现遍历菜单的功能。
菜单组件:
public abstract class MenuComponent {
//菜单名
protected String menuName;
//菜单层级
protected int level;
//添加子菜单
public void addMenu(MenuComponent menuComponent){}
//移除子菜单
public void removeMenu(MenuComponent menuComponent){}
//获取指定的子菜单
public MenuComponent getChildMenu(int index){
return null;
}
//获取菜单名称
public String getMenuName(){
return menuName;
}
//打印菜单名称(子菜单或菜单项)
public abstract void printMenu();
}
菜单:
import java.util.ArrayList;
import java.util.List;
public class Menu extends MenuComponent{
//存储菜单或者菜单项
private List menuComponentList = new ArrayList<>();
public Menu(String menuName,int level){
this.menuName = menuName;
this.level = level;
}
@Override
public void addMenu(MenuComponent menuComponent) {
menuComponentList.add(menuComponent);
}
@Override
public void removeMenu(MenuComponent menuComponent) {
menuComponentList.remove(menuComponent);
}
@Override
public MenuComponent getChildMenu(int index) {
return menuComponentList.get(index);
}
@Override
public void printMenu() {
//打印菜单名称
for (int i=0;i
菜单项:
public class MenuItem extends MenuComponent{
public MenuItem(String menuName,int level){
this.menuName = menuName;
this.level = level;
}
@Override
public void printMenu() {
for (int i=0;i
客户端:
public class Client{
public static void main(String[] args) {
//创建根目录
MenuComponent menuComponent = new Menu("系统管理",1);
//添加2个子菜单项
menuComponent.addMenu(new MenuItem("老师管理",2));
MenuComponent menu2 = new Menu("学生管理",2);
//创建2级目录
menu2.addMenu(new MenuItem("新增学生",3));
menu2.addMenu(new Menu("修改学生",3));
menu2.addMenu(new MenuItem("修改学生",3));
menu2.addMenu(new Menu("删除学生",3));
menuComponent.addMenu(menu2);
menuComponent.printMenu();
}
}
运行结果如下:
优点:
1、定义类层次结构更清晰,提高复用性。
2、简化客户端代码,统一对待单个对象和组合对象。
3、更容易在组合对象上新增功能。
缺点:
1、设计较复杂,增加系统实现难度。
2、不容易限制容器构件中的构件。
应用场景:
1、操作的对象具有递归树形结构时。
2、需要统一对待单个对象和组合对象时。
符合的设计原则:
1、组合复用原则(Composite Reuse Principle)
组合模式是组合复用原则最典型的体现,它通过组合方式实现对对象的复用。
2、开闭原则(Open Close Principle)
组合模式对扩展开放,可以通过添加新的叶节点或容器实现扩展,而无需修改原有代码。
3、单一职责原则(Single Responsibility Principle)
组合模式中各部分职责明确,容器构件用于存储组件,叶构件用于基本行为。
4、里氏替换原则(Liskov Substitution Principle)
组合模式确保所有构件遵循统一接口约定,父对象能被子对象替换。
5、依赖倒转原则(Dependence Inversion Principle)
组合模式依据抽象类而不是具体类进行组合,符合依赖倒转原则。
组合模式通过将对象组织成树形结构,模拟出复杂对象的结构关系,然后统一处理个别对象和组合对象,它充分利用了递归和层次性的对象模型来模拟复杂对象,但增加了系统的复杂性。应根据需要权衡使用,不能滥用。
综上,组合模式通过递归组合实现统一管理复杂对象,但会增加系统复杂度,需要谨慎使用。