JAVA设计模式之组合模式

191 阅读2分钟

本文介绍23种设计模式之组合模式。

定义

允许将对象组合成树形结构来表现“整体/部分”的层次结构。组合能让用户以一致的方式来处理个别对象及对象组合。

描述

  • 模式名称:COMPOSITE(组合)
  • 类型:对象结构型模式
  • 意图:将对象组合成树形结构以表示“部分 -整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
  • 适用性:
    • 想表示对象的部分-整体层次结构。
    • 你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
  • 效果:
  • 优点:
    • 定义了包含基本对象和组合对象的类层次结构。
    • 简化客户代码。
    • 使得更容易增加新类型的组件。
  • 缺点:
    • 很难限制组合中的组件。

类图

树形结构

1629682252(1).png

组合的树形结构分为整体和部分,因此component(组件)包含了composite(组合)和leaf(叶子节点)

1629682728(1).png

  1. Component(组件):为组合的所有对象定义一个接口,不管是组合还是叶子节点。
  2. Leaf(叶子节点):定义了组合中元素的行为。
  3. Composite(组合):定义组件的行为,这样的组件具有叶子节点。它的主要作用是存储和管理子部件,通常包含 add(Component)、remove(Component)、getChild(int) 等方法。
  4. 注意:所有的组件都实现了相同的接口,有些方法可能并不适合某些节点。例如 Leaf没有add,remove等操作,最好是抛出异常或者空实现。

实现代码

设计一个菜单,菜单中包含了子菜单和菜单项。

Component

public abstract class Component {



    public void add(Component component){
        throw new UnsupportedOperationException();
    }

    public void remove(Component component){
        throw new UnsupportedOperationException();
    }

    public Component getChild(int index){
        throw new UnsupportedOperationException();
    }


    public String getName(){
        throw new UnsupportedOperationException();
    }

    public String getDescription(){
        throw new UnsupportedOperationException();
    }
    public Double getPrice(){
        throw new UnsupportedOperationException();
    }

    public void print(){
        throw new UnsupportedOperationException();
    }
}

Leaf

public class Leaf extends Component {
    private String name;
    private Double price;
    private String description;


    public Leaf(String name, Double price, String description) {
        this.name = name;
        this.price = price;
        this.description = description;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public Double getPrice() {
        return price;
    }

    @Override
    public String getDescription() {
        return description;
    }

    @Override
    public void print() {
        System.out.println("树叶" + name + ":被访问!");
    }
}

Composite

public class Composite extends Component {

    private ArrayList<Component> list = new ArrayList<>();
    private String name;
    private String desc;

    public Composite(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

    @Override
    public void add(Component component) {
        list.add(component);
    }

    @Override
    public void remove(Component component) {
        list.remove(component);
    }

    @Override
    public Component getChild(int index) {
        return list.get(index);
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public String getDescription() {
        return desc;
    }

    @Override
    public void print() {
        System.out.println("树枝" + name + ":被访问!");
        Iterator<Component> iterator = list.iterator();
        while (iterator.hasNext()){
            Component next = iterator.next();
            next.print();
        }
    }
}

Client

public class Client {
    public static void main(String[] args) {
        Component component1 = new Composite("菜单1","早餐");
        Component component2 = new Composite("菜单2","午餐");
        Component component3 = new Composite("菜单3","晚餐");

        component1.add(new Leaf("面包",1d,""));
        component1.add(new Leaf("牛奶",3d,""));
        component1.add(new Leaf("鸡蛋",2d,""));

        Composite composite = new Composite("豪华晚餐", "");
        composite.add(new Leaf("神户牛肉",3000d,""));
        component3.add(composite);

        Component all = new Composite("总菜单","");
        all.add(component1);
        all.add(component2);
        all.add(component3);

        all.print();


    }
}

执行结果:
树枝总菜单:被访问!
树枝菜单1:被访问!
树叶面包:被访问!
树叶牛奶:被访问!
树叶鸡蛋:被访问!
树枝菜单2:被访问!
树枝菜单3:被访问!
树枝豪华晚餐:被访问!
树叶神户牛肉:被访问!

1629684905(1).png