组合模式(结构型)

  在电脑磁盘里有文件和文件夹,文件夹里又可以放文件和文件夹,这个磁盘可以看做是一个树状结构,磁盘里的文件可以看做叶子,文件夹看做枝干。文件夹其实也是文件的一种形式,对它们可以进行相同的操作(复制、粘贴、删除)。
  再来说说Android中的View和ViewGroup,ViewGroup是继承于View,因此ViewGroup和View可以同等看待。不同的是ViewGroup是一个容器,里面可以放View和ViewGroup,这是不是和上面文件的例子简直一毛一样。这就是组合模式。

定义:将对象组合成树形结构以表示“部分-整体”的层次结构,使用户对单个对象和组合对象的使用具有一致性。

结构

  • 组件:组合中的对象声明接口或抽象类,实现所有类共有接口的默认行为
  • 叶子:叶子对象,组件的实现类。叶子结点没有子结点
  • 容器:容器对象,组件的实现类,含有子节点,并实现了与子部件有关的操作

适用场景

  • 表示对象的“部分-整体”层次结构时
  • 从一个整体中能够独立出部分模块或功能的场景

UML类图
这里写图片描述

下面就是组合模式的代码实现,以文件和文件夹作为例子:
Component(组件)

//这里采用抽象类的方式
public abstract class File {
    String name;
    //增加这个方法,可以弥补违反依赖倒置原则的不足
    //是否为文件夹
    public abstract boolean isFolder();
    public abstract void delete();
}

Composite(容器)

public class Folder extends File {
    List<File> mList;
    int mChildNumber;
    public Folder(String name){
        mList = new ArrayList<>();
        this.name = name;
    }
    @Override
    public boolean isFolder() {
        //因为是文件夹,所以返回true
        return true;
    }
    @Override
    public void delete() {
        //先删除子文件,再删除自身
        for(int i=0;i<mChildNumber;i++){
            File file = getFile(i);
            file.delete();
        }
        System.out.println("删除了"+name+"文件夹");
    }
    public void addFile(File file){
        mList.add(file);
        mChildNumber++;
    }
    public void removeFile(File file){
        mList.remove(file);
        mChildNumber--;
    }
    public File getFile(int index){
        return mList.get(index);
    }
}

Leaf(叶子)

public class ImageFile extends File {
    public ImageFile(String name){
        this.name = name;
    }
    @Override
    public boolean isFolder() {
        return false;
    }
    @Override
    public void delete() {
        System.out.println("删除了"+name+"文件");
    }
}

public class TextFile extends File {
    public TextFile(String name){
        this.name = name;
    }
    @Override
    public boolean isFolder() {
        return false;
    }
    @Override
    public void delete() {
        System.out.println("删除了"+name+"文件");
    }
}

Test

public class Test {
    public static void main(String[] args){
        Folder folder1 = new Folder("folder1");

        ImageFile imageFile1 = new ImageFile("abc1.jpg");
        ImageFile imageFile2 = new ImageFile("abc2.jpg");
        TextFile textFile1 = new TextFile("abc1.txt");
        TextFile textFile2 = new TextFile("abc2.txt");
        Folder folder2 = new Folder("folder2");
        folder2.addFile(textFile2);
        folder2.addFile(imageFile2);
        folder1.addFile(imageFile1);
        folder1.addFile(textFile1);
        folder1.addFile(folder2);

        for(int i=0;i<folder1.mChildNumber;i++){
            File file = folder1.getFile(i);
            file.delete();
        }
    }
}


总结:组合对象的关键在于它定义了一个抽象构建类,它既可表示叶子对象,也可表示容器对象,客户仅仅需要针对这个抽象构建进行编程,无须知道他是叶子对象还是容器对象,都是一致对待(也提供了区分的方法isFolder)。组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,使得增加新构件也更容易;从上面代码也可以看出,基于这种树状结构的对象组合模式下,实现删除文件夹时的递归操作(先删除子文件,再删除自身)也是很轻松的。


参考:http://www.cnblogs.com/chenssy/p/3299719.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值