设计模式(结构型模式)组合模式

目录

    • 一、简介
    • 二、图形界面
      • 2.1、统一组件接口
      • 2.2、叶子节点
      • 2.3、组合节点
      • 2.4、使用
      • 2.5、优缺点

一、简介

  组合模式是一种结构型设计模式,它允许你将对象组合成树形结构以表示“整体-部分”的层次结构。组合模式使得客户端对单个对象和组合对象的处理具有一致性,可以像处理单个对象一样来处理组合对象。在组合模式中,有两种主要类型的对象:

  • 叶子(Leaf): 叶子是组合结构的最底层对象,它没有子元素。它实现了组合中的统一接口,但是不包含其他子对象。
  • 组合(Composite): 组合是包含子元素的对象。它也实现了统一的接口,但是除了执行基本操作外,它还能管理其子元素。
    这种模式使得客户端可以递归地处理单个对象和组合对象,而无需了解处理的是哪种类型的对象。

组合模式通常用于以下情况:

  • 需要表示对象的整体-部分层次结构。
  • 希望用户统一地对待单个对象和组合对象。
  • 希望能够以相同的方式处理单个对象和组合对象,而不需要进行类型检查。

  总而言之,组合模式允许你创建树形结构,其中叶子和组合对象都实现了相同的接口,并且可以递归地进行处理。这种设计模式使得代码更具扩展性,允许以统一的方式处理对象集合的层次结构。

二、图形界面

  其实组合模式到处可见,工作中你用到了都没在意过,比如树形菜单、文件系统中,文件和文件夹等。

2.1、统一组件接口

  我们这里定义一个组件接口

// 统一的组件接口
public interface UIComponent {
    void draw();
}

2.2、叶子节点

  我们有文本框和按钮两个组件实现了上述的接口。

// 输入框组件:文本框
public class TextBox implements UIComponent {
    private String placeholder;

    public TextBox(String placeholder) {
        this.placeholder = placeholder;
    }

    public void draw() {
        System.out.println("开始画一个输入框: " + placeholder);
    }
}

// 叶子节点:按钮
public class Button implements UIComponent {
    private String label;

    public Button(String label) {
        this.label = label;
    }

    public void draw() {
        System.out.println("开始画一个按钮: " + label);
    }
}

2.3、组合节点

  我们组合节点面板也实现了组件接口,然后它持有其他组件的列表,并且提供相应添加、删除接口。

import java.util.ArrayList;
import java.util.List;

// 组合节点:面板
public class Panel implements UIComponent {

    private String title;

    private List<UIComponent> components;

    public Panel(String title) {
        this.title=title;
        this.components = new ArrayList<>();
    }

    public void addComponent(UIComponent component) {
        components.add(component);
    }

    public void removeComponent(UIComponent component) {
        components.remove(component);
    }

    public void draw() {
        System.out.println("开始画一个面板:");
        for (UIComponent component : components) {
            component.draw();
        }
    }
}

2.4、使用

  测试代码如下:

public class UIClient {
    public static void main(String[] args) {
        // 创建输入框
        TextBox textBox = new TextBox("Enter your name");

        // 创建按钮
        Button btn1 = new Button("提交");
        Button btn2 = new Button("取消");

        // 创建面板并添加按钮和输入框
        Panel panel = new Panel("意见反馈");
        panel.addComponent(textBox);
        panel.addComponent(btn1);
        panel.addComponent(btn2);

        // 绘制整个界面
        panel.draw();
    }
}

运行结果:

开始画一个面板:
开始画一个输入框: Enter your name
开始画一个按钮: 提交
开始画一个按钮: 取消

2.5、优缺点

  组合模式的优点和缺点如下:

优点:

  • 统一性: 该模式使得客户端代码可以统一地处理单个对象和组合对象,无需区分操作对象的类型。
  • 灵活性: 可以在组合结构中添加或移除对象,无需修改现有代码,使得系统更加灵活、可扩展。
  • 简化客户端代码: 使用组合模式,客户端代码更简洁清晰,无需过多的条件判断逻辑,提高代码可读性。
  • 易于扩展: 方便地增加新类型的对象,通过继承组合模式中的抽象类或实现统一接口即可。

缺点:

  • 限制类型: 因为组合模式统一了叶子和组合对象,可能导致一些限制。例如,对于叶子对象来说,如果某些方法在它们身上没有意义,就需要对这些方法进行空实现或者抛出异常。
  • 难以限制组合中的元素类型: 在某些情况下,可能需要限制组合中包含的对象类型,而组合模式难以提供这样的限制。
  • 可能带来过多的一般性设计: 对于简单的情况,使用组合模式可能带来过多的抽象,增加了设计的一般性,使得系统变得过于复杂。

  虽然组合模式有一些缺点,但在合适的情况下,通过提供统一的接口来处理对象的整体-部分结构,组合模式可以使得代码更加清晰、灵活,并且更易于扩展,所以相比继承我更推荐组合模式。

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