前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >结构型-Composite

结构型-Composite

作者头像
acc8226
发布2022-05-17 15:57:14
1980
发布2022-05-17 15:57:14
举报
文章被收录于专栏:叽叽西

组合模式的原理与实现在 GoF 的《设计模式》一书中,组合模式是这样定义的:

Compose objects into tree structure to represent part-whole hierarchies.Composite lets client treat individual objects and compositions of objects uniformly.

翻译成中文就是:将一组对象组织(Compose)成树形结构,以表示一种“部分 - 整体”的层次结构。组合让客户端(在很多设计模式书籍中,“客户端”代指代码的使用者。)可以统一单个对象和组合对象的处理逻辑。

接下来,对于组合模式,我举个例子来给你解释一下。

假设我们有这样一个需求:设计一个类来表示文件系统中的目录,能方便地实现下面这些功能:

  • 动态地添加、删除某个目录下的子目录或文件;
  • 统计指定目录下的文件个数;
  • 统计指定目录下的文件总大小。
代码语言:javascript
复制
package pattern.structural.composite;

public abstract class FileSystemNode {

    protected String path;

    public FileSystemNode(String path) {
        this.path = path;
    }

    public abstract long countNumOfFiles();

    public abstract long countSizeOfFiles();

    public String getPath() {
        return path;
    }

}

文件类

代码语言:javascript
复制
package pattern.structural.composite;

public class File extends FileSystemNode {

    public File(String path) {
        super(path);
    }
    
    @Override
    public long countNumOfFiles() {
        java.io.File file = new java.io.File(super.path);
        if (file.exists()) {
            return 1;
        }
        return 0;   
    }

    @Override
    public long countSizeOfFiles() {
        java.io.File file = new java.io.File(super.path);
        if (file.exists()) {
            return file.length();
        }
        return 0;       
    }

}

目录类

代码语言:javascript
复制
package pattern.structural.composite;

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

public class Directory extends FileSystemNode {
    
    private List<FileSystemNode> subNodes = new ArrayList<>();
    
    public Directory(String path) {
        super(path);
    }
    
    @Override
    public long countNumOfFiles() {
        int countNum = 0;
        for (int i = 0; i < this.subNodes.size(); i++) {
            countNum += this.subNodes.get(i).countNumOfFiles();
        }       
        return countNum;
    }

    @Override
    public long countSizeOfFiles() {
        int countSize = 0;
        for (int i = 0; i < this.subNodes.size(); i++) {
            countSize += this.subNodes.get(i).countSizeOfFiles();
        }       
        return countSize;
    }
    
    public void addSubNode(FileSystemNode fileOrDir) {
        this.subNodes.add(fileOrDir);
    }

    public void removeSubNode(FileSystemNode fileOrDir) {
        int size = subNodes.size();
        int i = 0;
        for (; i < size; ++i) {
            if (subNodes.get(i).getPath().equalsIgnoreCase(fileOrDir.getPath())) {
                break;
            }
        }
        if (i < size) {
            subNodes.remove(i);
        }
    }
}

Main 方法调用

代码语言:javascript
复制
package pattern.structural.composite;

public class Main {

    public static void main(String[] args) {        
        Directory rootDir = new Directory("D:\\K_Workspace\\111\\src\\demo");
        buildFileSystemNode(rootDir);
        
        System.out.println(rootDir.countNumOfFiles());
        System.out.println(rootDir.countSizeOfFiles()); 
    }
    
    private static void buildFileSystemNode(Directory dir) {
        java.io.File file = new java.io.File(dir.getPath());
        for (java.io.File f : file.listFiles()) {
            if (f.isFile()) {
                dir.addSubNode(new File(f.getPath()));
            } else if (f.isDirectory()) {
                Directory directory = new Directory(f.getPath());
                dir.addSubNode(directory);
                buildFileSystemNode(directory);
            }
        }
    }

}

组合模式的设计思路,与其说是一种设计模式,倒不如说是对业务场景的一种数据结构和算法的抽象。其中,数据可以表示成树这种数据结构,业务需求可以通过在树上的递归遍历算法来实现。

组合模式,将一组对象组织成树形结构,将单个对象和组合对象都看做树中的节点,以统一处理逻辑,并且它利用树形结构的特点,递归地处理每个子树,依次简化代码实现。使用组合模式的前提在于,你的业务场景必须能够表示成树形结构。所以,组合模式的应用场景也比较局限,它并不是一种很常用的设计模式。

参考

设计模式之美设计模式代码重构-极客时间 https://time.geekbang.org/column/intro/250

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-05-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档