结构型模式(三):组合模式

1、模式的定义与特点

组合(Composite)模式:有时又叫作部分-整体模式,它是一种将对象组合成树状的层次结构的模式,用来表示“部分-整体”的关系,使用户对单个对象和组合对象具有一致的访问性。

优点:
1、组合模式使得客户端代码可以一致地处理单个对象和组合对象,无须关心自己处理的是单个对象,还是组合对象,这简化了客户端代码;
2、更容易在组合体内加入新的对象,客户端不会因为加入了新的对象而更改源代码,满足“开闭原则”;

缺点:
1、设计较复杂,客户端需要花更多时间理清类之间的层次关系;
2、不容易限制容器中的构件;
3、不容易用继承的方法来增加构件的新功能;

2、模式的结构

2.1 组合模式的主要角色

1、抽象构件(Component)角色:它的主要作用是为树叶构件和树枝构件声明公共接口,并实现它们的默认行为。
在透明式的组合模式中抽象构件还声明访问和管理子类的接口;
在安全式的组合模式中不声明访问和管理子类的接口,管理工作由树枝构件完成。

2、树叶构件(Leaf)角色:或叶子节点角色,是组合中的叶节点对象,它没有子节点,用于实现抽象构件角色中声明的公共接口。
3、树枝构件(Composite)角色:或复合节点角色,是组合中的分支节点对象,它有子节点。它实现了抽象构件角色中声明的接口,它的主要作用是存储和管理子部件,通常包含 Add()、Remove()、GetChild() 等方法。

2.2 组合模式分类

分为透明式的组合模式和安全式的组合模式。
1、透明方式:在该方式中,由于抽象构件声明了所有子类中的全部方法,所以客户端无须区别树叶对象和树枝对象,对客户端来说是透明的。
但其缺点是:树叶构件本来没有 Add()、Remove() 及 GetChild() 方法,却要实现它们(空实现或抛异常),这样会带来一些安全性问题。
其结构图如图 1 所示。
在这里插入图片描述

图1 透明式的组合模式的结构图

2、安全方式:在该方式中,将管理子构件的方法移到树枝构件中,抽象构件和树叶构件没有对子对象的管理方法,这样就避免了上一种方式的安全性问题,但由于叶子和分支有不同的接口,客户端在调用时要知道树叶对象和树枝对象的存在,所以失去了透明性。
其结构图如图 2 所示。
在这里插入图片描述

图2 安全式的组合模式的结构图

3、组合模式的应用场景

1、在需要表示一个对象整体与部分的层次结构的场合。
2、要求对用户隐藏组合对象与单个对象的不同,用户可以用统一的接口使用组合结构中的所有对象的场合。

4、模式的实现

(请参见下文的PPT素材第7页–绘图实例)
在这里插入图片描述

图3 示例代码结构

抽象构件角色:

package com.example.designpattern.composite;

/**
 * @author Administrator
 * @date 2020/7/30
 * 抽象组价角色
 */
interface IGraphic {
    void draw();
}

树叶构件角色1:

package com.example.designpattern.composite;

/**
 * @author Administrator
 * @date 2020/7/30
 * 叶子节点角色
 */
class LineImpl implements IGraphic {
    @Override
    public void draw() {
        System.out.println("一条直线");
    }
}

树叶构件角色2:

package com.example.designpattern.composite;

/**
 * @author Administrator
 * @date 2020/7/30
 * 叶子节点角色
 */
class CircleImpl implements IGraphic {
    @Override
    public void draw() {
        System.out.println("一个圆形");
    }
}

树叶构件角色3:

package com.example.designpattern.composite;

/**
 * @author Administrator
 * @date 2020/7/30
 * 叶子节点角色
 */
class RectangleImpl implements IGraphic {
    @Override
    public void draw() {
        System.out.println("一个长方形");
    }
}

树枝构件角色:

package com.example.designpattern.composite;

import java.util.Vector;

/**
 * @author Administrator
 * @date 2020/7/30
 * 复合/合成节点角色
 * 应该包含子节点
 * 应该具有操作子节点的方法
 */
class Picture implements IGraphic {
    /**
     * 用来存放管理子节点
     */
    private Vector<IGraphic> vector = new Vector<>();

    public void add(IGraphic iGraphic) {
        vector.add(iGraphic);
    }

    public void remove(IGraphic iGraphic) {
        vector.remove(iGraphic);
    }

    public IGraphic getChild(int index) {
        return vector.get(index);
    }

    @Override
    public void draw() {
        System.out.println("画一幅画:");

        for (IGraphic i : vector) {
            i.draw();
        }
    }

}

调用:

package com.example.designpattern.composite;

/**
 * @author Administrator
 * @date 2020/7/30
 */
class Client {
    public static void main(String[] args) {
        //根节点,应该是一个合成节点
        Picture root = new Picture();

        //叶子节点
        IGraphic line = new LineImpl();
        IGraphic circle = new CircleImpl();
        IGraphic rectangle = new RectangleImpl();

        //添加三个叶子节点
        root.add(line);
        root.add(circle);
        root.add(rectangle);

        //创建一个合成节点
        Picture picture = new Picture();
        picture.add(new LineImpl());
        picture.add(new CircleImpl());

        //将合成节点添加到根节点
        root.add(picture);

        //画整个树
        root.draw();
    }
}

测试结果:
在这里插入图片描述

图4 测试结果

5、PPT素材

在这里插入图片描述

PPT 01

在这里插入图片描述

PPT 02

在这里插入图片描述

PPT 03

在这里插入图片描述

PPT 04

在这里插入图片描述

PPT 05

在这里插入图片描述

PPT 06

在这里插入图片描述

PPT 07

在这里插入图片描述

PPT 08

在这里插入图片描述

PPT 09

在这里插入图片描述

PPT 10

在这里插入图片描述

PPT 11

微信公众号: TechU
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值