大话设计模式十四:组合模式

一.模式定义

组合模式(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. 

 

二.模式要素

Component: 抽象构件
Leaf: 叶子构件
Composite: 容器构件
Client: 客户类

 

三.举例说明

文件系统就是典型的树状结构。如果遇到普通文件或者图片则是叶节点,如果遇到文件夹,则看其中有无其他文件格式,无就是叶子节点,有的话就是指节点。实现这样一个系统实际上并不难。

四.具体代码

Format.java

package compositePattern;

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

/**
 * @program: Test
 * @description: 文件格式
 * @author: Lei Dong
 * @create: 2019-04-21 13:58
 **/
public abstract class Format {
    List<Format> list = new ArrayList<>();
    private String name;
    private int depth;

    public Format(String name, int depth) {
        this.name = name;
        this.depth = depth;
    }

    abstract void add(Format f);

    abstract void remove(Format f);

    abstract void showDetail();

    void showName() {
        for (int i = 0; i < depth - 1; i++) {
            System.out.print("--");
        }
        System.out.println(name);
    }
}

Image.java

package compositePattern;

/**
 * @program: Test
 * @description: Image
 * @author: Lei Dong
 * @create: 2019-04-21 14:06
 **/
public class Image extends Format {
    public Image(String name, int depth) {
        super(name, depth);
    }

    @Override
    void add(Format f) {

    }

    @Override
    void remove(Format f) {

    }

    @Override
    void showDetail() {
        showName();
    }
}

File.java

package compositePattern;

/**
 * @program: Test
 * @description: File
 * @author: Lei Dong
 * @create: 2019-04-21 14:08
 **/
public class File extends Format {
    public File(String name, int depth) {
        super(name, depth);
    }

    @Override
    void add(Format f) {
        try {
            throw new Exception("无法增加文件格式");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    void remove(Format f) {
        try {
            throw new Exception("无法移除文件格式");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    void showDetail() {
        showName();
    }
}

Folder.java

package compositePattern;

/**
 * @program: Test
 * @description: /home
 * @author: Lei Dong
 * @create: 2019-04-21 14:02
 **/
public class Folder extends Format {
    public Folder(String name, int depth) {
        super(name, depth);
    }

    @Override
    void add(Format f) {
        list.add(f);
    }

    @Override
    void remove(Format f) {
        if (list.contains(f)) {
            list.remove(f);
        } else {
            try {
                throw new Exception("无法移除文件格式");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    void showDetail() {
        showName();
        for (Format ele : list) {
            ele.showDetail();
        }
    }
}

Main.java

package compositePattern;

/**
 * @program: Test
 * @description: Main
 * @author: Lei Dong
 * @create: 2019-04-21 13:56
 **/
public class Main {
    public static void main(String[] args) {
        Folder folder = new Folder("home", 1);

        File file = new File("test.txt",2);
        Image image = new Image("test.png", 2);
        Folder folder1 = new Folder("leidong", 2);

        folder.add(file);
        folder.add(image);

        Image image1 = new Image("haha.png", 3);
        File file1 = new File("hehe.txt", 3);

        folder1.add(image1);
        folder1.add(file1);

        folder.add(folder1);

        folder.showDetail();
    }
}

运行结果:

 

五.总结

1.组合模式的优点
(1)可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,使得增加新构件也更容易。
(2)客户端调用简单,客户端可以一致的使用组合结构或其中单个对象。
(3)定义了包含叶子对象和容器对象的类层次结构,叶子对象可以被组合成更复杂的容器对象,而这个容器对象又可以被组合,这样不断递归下去,可以形成复杂的树形结构。
(4)更容易在组合体内加入对象构件,客户端不必因为加入了新的对象构件而更改原有代码。

2.组合模式的缺点
(1)使设计变得更加抽象,对象的业务规则如果很复杂,则实现组合模式具有很大挑战性,而且不是所有的方法都与叶子对象子类都有关联。
(2)增加新构件时可能会产生一些问题,很难对容器中的构件类型进行限制。

3.模式适用环境
在以下情况下可以使用组合模式:
(1)需要表示一个对象整体或部分层次,在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,可以一致地对待它们。
(2)让客户能够忽略不同对象层次的变化,客户端可以针对抽象构件编程,无须关心对象层次结构的细节。
(3)对象的结构是动态的并且复杂程度不一样,但客户需要一致地处理它们。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值