组合模式-Composite(Java实现)

组合模式-Composite

Composite模式使得用户对单个对象和组合对象的使用具有一致性.

以<<图解设计模式>>的文件例子来说: 文件夹是文件的组合, 文件是单个对象, 文件夹是多个文件的组合. 不过对用户来说, 无论是文件还是文件夹, 他希望使用一个统一的方法来管理他们.这就需要将他们再次抽象出来.

解读一下这个类图就明白了:

1. 文件是一个组件

2. 文件夹也是一个组件

3. 文件夹里有很多组件:

3.1 文件夹里可以有文件

3.2 文件夹里可以有文件夹

Component抽象类

这是文件 文件夹的抽象定义类--组件类

/**
 * 这里是文件/文件夹 的统一抽象类 "组件类"
 */
public abstract class Component {
    /**
     * parent是父组件的指针, 也就是本例子中的"父级目录"
     */
    protected Component parent;

    /**
     * 获取组件名字
     */
    public abstract String getName();

    /**
     * 获取组件的大小
     */
    public abstract int getSize();

    /**
     * @implNote 向一个组件中添加一个组件.
     * @implSpec 组合模式中的叶子(Leaf)节点不可以使用这个方法, 用例子说明的话:
     * 一个文件不可以添加一个文件或文件夹, 只能是文件夹来添加文件或文件夹
     */
    public Component add(Component entry) {
        throw new RuntimeException("不支持此类操作...");
    }

    public void printList() {
        printList("");
    }

    protected abstract void printList(String prefix);

    /**
     * 获取绝对路径
     */
    public String getFullName() {
        StringBuilder fullName = new StringBuilder();
        Component entry = this;
        do {
            fullName.insert(0, "/" + entry.getName());
            entry = entry.parent;
        } while (entry != null);
        return fullName.toString();
    }

    /**
     * 其中的getSize() 会被子类重写, 因为文件大小可以很容易知道, 但是文件夹大小需要递归计算
     */
    @Override
    public String toString() {
        return getName() + " (" + getSize() + ")";
    }
}

MyFile类

MyFile类在组合模式中是Leaf(叶子)节点, 因为他不会包含其他组件.

我们可以把组件模式想象成一颗树(绿色表示文件夹, 橙色表示文件):

组合模式的叶子节点指的是文件节点, 因为文件永远也不会有子节点.

而绿的c1节点虽然现在是叶子节点, 但是如果给c1文件夹添加了一个文件的话, 他就不再是叶子节点了.

组合模式里无法继续添加子节点的就被称作Leaf(叶子)

上面那个树, 等价于下图:

public class MyFile extends Component {
    private String name;
    private int size;

    public MyFile(String name, int size) {
        this.name = name;
        this.size = size;
    }

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

    @Override
    public int getSize() {
        return this.size;
    }

    @Override
    protected void printList(String prefix) {
        System.out.println(prefix + "/" + this.toString());
    }
}

MyDirectory类

MyDirectory类作为一个文件夹, 可以包含其他组件(文件/文件夹)

public class MyDirectory extends Component {

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

    public MyDirectory(String name) {
        this.name = name;
    }

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

    /**
     * 获取文件夹的大小:
     * 1. size一开始是0
     * 2. 如果是文件, 那么直接把文件的大小加到size上
     * 3. 如果是文件夹, 那么就递归地查出该文件夹的大小, 然后加到size上.
     */
    @Override
    public int getSize() {
        int size = 0;
        for (Component entry : substance) {
            size += entry.getSize();
        }
        return size;
    }

    /**
     * 像一个文件夹中添加一个文件或文件夹
     */
    @Override
    public Component add(Component entry) {
        substance.add(entry);
        entry.parent = this;
        return this;
    }

    /**
     * 1. 打印当前目录的路径
     * 2. 然后打印出子目录, 子文件的路径
     * 3. 子目录再打印子子目录/子子文件的路径...如此递归
     */
    @Override
    protected void printList(String prefix) {
        System.out.println(prefix + "/" + this.toString());
        for (Component entry : substance) {
            entry.printList(prefix + "/" + name);
        }
    }
}

  

Main

用于测试运行

public class Main {
    public static void main(String[] args) {

        /* 本例子目录结构如下:
          一级目录   二级目录   三级目录
            a1
            |-------b1
            |-------b2
            |
            a2
            |-------c1
                    |-------Composite.java
                    |-------king.python

            |-------c2
         */

        MyDirectory a1 = new MyDirectory("a1");
        MyDirectory a2 = new MyDirectory("a2");

        MyDirectory b1 = new MyDirectory("b1");
        MyDirectory b2 = new MyDirectory("b2");
        a1.add(b1).add(b2);

        MyDirectory c1 = new MyDirectory("c1");
        MyDirectory c2 = new MyDirectory("c2");
        a2.add(c1).add(c2);

        MyFile java = new MyFile("Composite.java", 100);
        MyFile python = new MyFile("king.python", 214);
        c1.add(java).add(python);

        /*-****** getFullName() ************-*/
        System.out.println(java.getFullName());
        System.out.println(python.getFullName());
        System.out.println("");
        /*-****** getFullName() ************-*/
        a1.printList();
        System.out.println("-----");
        a2.printList();
    }
}

原文地址:https://www.cnblogs.com/noKing/p/9020119.html

时间: 2024-10-30 02:00:53

组合模式-Composite(Java实现)的相关文章

设计模式 - 组合模式(composite pattern) 详解

组合模式(composite pattern) 详解 本文地址: http://blog.csdn.net/caroline_wendy 组合模式: 允许你将对象组合成树形结构来表现"整体/部分"层次结构. 组合能让客户以一致的方法处理个别对象以及组合对象. 建立组件类(Component), 组合类(composite)和叶子类(leaf)继承组件类, 客户类(client)直接调用最顶层的组合类(composite)即可. 具体方法: 1. 组件类(component), 包含组合

设计模式 - 组合模式(composite pattern) 迭代器(iterator) 详解

组合模式(composite pattern) 迭代器(iterator) 详解 本文地址: http://blog.csdn.net/caroline_wendy 参考组合模式(composite pattern): http://blog.csdn.net/caroline_wendy/article/details/36895627 在组合模式(composite pattern)添加迭代器功能, 遍历每一个组合(composite)的项. 具体方法: 1. 抽象组件类(abstract

设计模式之组合模式---Composite Pattern

模式的定义 组合模式(Composite Pattern)定义如下: Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly. 将对象组合成树形结构以表示"部分-整体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性.

组合模式(Composite Pattern)

转:http://www.cnblogs.com/doubleliang/archive/2011/12/27/2304104.html 简而言之,就是让所有的叶子节点执行相同的操作!!!!!!!!!!!!!!! 组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性. 有时候又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构

设计模式之组合模式(Composite)摘录

23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象.创建型模式有两个不断出现的主旋律.第一,它们都将关于该系统使用哪些具体的类的信息封装起来.第二,它们隐藏了这些类的实例是如何被创建和放在一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口.因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以

设计模式(七)组合模式Composite(结构型)

设计模式(七)组合模式Composite(结构型) 1. 概述 在数据结构里面,树结构是很重要,我们可以把树的结构应用到设计模式里面. 例子1:就是多级树形菜单. 例子2:文件和文件夹目录 2.问题 我们可以使用简单的对象组合成复杂的对象,而这个复杂对象有可以组合成更大的对象.我们可以把简单这些对象定义成类,然后定义一些容器类来存储这些简单对象.客户端代码必须区别对象简单对象和容器对象,而实际上大多数情况下用户认为它们是一样的.对这些类区别使用,使得程序更加复杂.递归使用的时候跟麻烦,而我们如何

说说设计模式~组合模式(Composite)

返回目录 何时能用到它? 组合模式又叫部分-整体模式,在树型结构中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦.对于今天这个例子来说,它可以很清楚的说明组合模式的用意,首先是一个Graphics对象,它表示是一绘图功能(树根),而circle,line和rectangle分别是简单的图形,它们内部不能再有其它图形了(相当于树叶),而picture是一个复杂图形,它由circle,line和rectangle组成(相当于树

设计模式 -- 组合模式(Composite)

写在前面的话:读书破万卷,编码如有神--------------------------------------------------------------------主要内容包括: 初识组合模式,包括:定义.结构.参考实现 体会组合模式,包括:场景问题.不用模式的解决方案.使用模式的解决方案 理解组合模式,包括:认识组合模式.安全性和透明性.父组件引用.环状引用.组合模式的优缺点 思考组合模式,包括:组合模式的本质.何时选用 参考内容: 1.<研磨设计模式> 一书,作者:陈臣.王斌 --

【设计模式】—— 组合模式Composite

前言:[模式总览]——————————by xingoo 模式意图 使对象组合成树形的结构.使用户对单个对象和组合对象的使用具有一致性. 应用场景 1 表示对象的 部分-整体 层次结构 2 忽略组合对象与单个对象的不同,统一的使用组合结构中的所有对象. 模式结构 [安全的组合模式] 这种组合模式,叶子节点,也就是单个对象不具有对象的控制功能.仅仅有简单的业务操作. 1 package com.xingoo.composite.safe; 2 3 import java.util.ArrayLis