Java设计模式之结构型-组合模式(UML类图+案例分析)

目录

一、基础概念

二、UML类图

三、角色设计

四、案例分析

1、基本实现

2、菜单遍历 

五、总结 


一、基础概念

组合模式(Composite Pattern)又叫部分-整体模式,它通过将对象组合成树形结构来表示“整体-部分”的层次关系,允许用户统一单个对象和组合对象的处理逻辑。

二、UML类图

Java设计模式之结构型-组合模式(UML类图+案例分析)_第1张图片

三、角色设计

角色 描述
抽象构件角色 定义参与组合对象的共有方法和属性,可以是接口或抽象类
叶构件角色 基本构件类,无子构件,实现抽象构件角色所定义的接口
容器构件角色 存储子构件,实现子构件的相关操作,定义子构件的添加、删除等方法
客户端 通过抽象组件操作组合部件的对象

四、案例分析

1、基本实现

抽象构件:

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方法。

综上,这段基础代码演示了通过组合模式将对象组合成树状层次结构,通过调用根节点操作使得递归调用所有子节点的操作,实现统一处理个别对象和组合对象的情形,以达到“合成复用原则”。

2、菜单遍历 

我们平时用到的管理系统肯定会有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();
    }

}

运行结果如下:

Java设计模式之结构型-组合模式(UML类图+案例分析)_第2张图片

五、总结 

优点:

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)

组合模式依据抽象类而不是具体类进行组合,符合依赖倒转原则。

组合模式通过将对象组织成树形结构,模拟出复杂对象的结构关系,然后统一处理个别对象和组合对象,它充分利用了递归和层次性的对象模型来模拟复杂对象,但增加了系统的复杂性。应根据需要权衡使用,不能滥用。

综上,组合模式通过递归组合实现统一管理复杂对象,但会增加系统复杂度,需要谨慎使用。

你可能感兴趣的:(Java,设计模式,java,设计模式,组合模式)