设计模式-组合模式

组合模式是一种结构模式,他将对象组织到树的结构当中去。用来描述整体与局部的关系。

模式结构

uml

组合模式包含3个角色:抽象构件、叶子构件、容器构件。

抽象构件可以使抽象类,也可以是接口。抽象构件为另两种构件对象的声明接口。其中包含有子类共有的方法。如:增加子构件、删除子构件、获取子构件等等。

叶子构件为叶子节点对象。叶子节点没有子节点,当调用叶子节点对象调用访问、管理子节点的方法时,可以采用抛出异常的方式处理。

容器构件为容器节点对象。容器节点对象中包含有叶子节点。它提供了一个集合用于存储叶子节点。

模式分类

组合模式分为透明组合模式和安全组合模式两种,区别如下:

透明组合模式:因为抽象模式中两个重要构件—容器构件和叶子构件都继承或实现抽象构件。那么如果抽象部件中拥有管理叶子构件的方法时,叶子构件应该是不包含这些方法的。由于采用继承或实现抽象构件,叶子构件会包含这些方法。所以我们必须设置,当叶子构件使用这些方法的时候,抛出异常等等的处理方法。这样做的优点是客户端程序无需分辨是叶子构件还是容器构件。但是违背了接口隔离原则。

安全组合模式:与透明组合模式相反,只在抽象构件中添加叶子构件和容器构件共有的方法。这样便可以解决透明组合模式。但是这样操作的话,当创建叶子节点对象时便不可以使用多态来创建。也就是说客户端程序必须分辨叶子构件和容器构件。这样会违背依赖倒置原则。

代码实现

例如,一个文件夹下面可以有图片、文本文件、视频文件。也可以包含文件夹。这种结构便可以使用组合模式。

抽象构件:

public abstract class AbstractFile {
    abstract public void add(AbstractFile element);
    abstract public void remove(AbstractFile element);
    abstract public void display();
}

文件夹(容器构件)

import java.util.ArrayList;

public class Folder extends AbstractFile {
    String fileName;
    ArrayList<AbstractFile> fileList = new ArrayList<>();

    Folder(String fileName){
        this.fileName = fileName;
    }

    @Override
    public void add(AbstractFile element) {
        fileList.add(element);
        System.out.println("element has been add");
    }

    @Override
    public void remove(AbstractFile element) {
        fileList.remove(element);
        System.out.println("element has been removed");
    }

    @Override
    public void display() {

        for(AbstractFile i : fileList){
            i.display();
        }
    }
}

图片文件(叶子构件)

public class ImageFile extends AbstractFile {
    private String fileName;
    ImageFile(String name){
        this.fileName = name;
    }

    @Override
    public void add(AbstractFile element) {
        System.out.println("cant do it");
    }

    @Override
    public void remove(AbstractFile element) {
        System.out.println("cant do it");
    }

    @Override
    public void display() {
        System.out.println("name: " + fileName + " type: ImageFile");
    }
}

视频文件(叶子构件)

public class VideoFile extends AbstractFile {
    private String fileName;

    VideoFile(String fileName){
        this.fileName = fileName;
    }

    @Override
    public void add(AbstractFile element) {
        System.out.println("cant do it");
    }

    @Override
    public void remove(AbstractFile element) {
        System.out.println("cant do it");
    }

    @Override
    public void display() {

        System.out.println("name: " + fileName + " type: VideoFile");

    }
}

文本文件(叶子构件)

public class TextFile extends AbstractFile {
    private String filename;

    TextFile(String filename){
        this.filename = filename;
    }

    @Override
    public void add(AbstractFile element) {
        System.out.println("cant do it");
    }

    @Override
    public void remove(AbstractFile element) {
        System.out.println("cant do it");
    }

    @Override
    public void display() {
        System.out.println("name: " + filename + " type: TextFile");
    }
}

客户端(测试类)

public class Client {
    public static void main(String[] args) {
        AbstractFile root = new Folder("root");
        AbstractFile video = new VideoFile("video");
        AbstractFile text = new TextFile("text");
        AbstractFile image = new ImageFile("image");
        root.add(video);
        root.add(text);
        root.add(image);
        root.display();
        System.out.println();
        root.remove(video);
        System.out.println();
        root.display();
    }
}

代码执行结果

name: video type: VideoFile
name: text type: TextFile
name: image type: ImageFile

element has been removed

name: text type: TextFile
name: image type: ImageFile

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值