【图解设计模式系列】The Composite Pattern: 组合模式

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

英文解释
allows you to compose objects into tree structures to represent part-whole hierarchies. Composite lets clients teat individual objects and compositions of objects uniformly.
allows us to build structures of objects in the form of trees that contain both compositions of objects and individual objects as nodes.
Using a composite structure, we can apply the same operations over both composites and individual objects. In other words, in most cases we can ignore the differences between composition of objects and individual objects.
在这里插入图片描述

在这里插入图片描述
组合模式包含了如下几个角色:

Component:是组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component子部件。
Leaf :在组合中表示叶子结点对象,叶子结点没有子结点。
Composite:定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加(add)和删除(remove)等。

实例

考虑一个杀毒软件的例子,杀毒软件在进行杀毒的时候就是使用的组合模式实现的。

用于访问和管理Component子组件

public abstract class AbstractFileComponent {
    protected String name;
    protected AbstractFileComponent(String name) {
        this.name = name;
    }
    protected void printDepth(int depth) {
        for (int i = 0; i < depth; ++i) {
            System.out.print('-');
        }
    }
    protected abstract void add(AbstractFileComponent component);
    protected abstract void remove(AbstractFileComponent component);
    protected abstract void killVirus(int depth);
}

叶子对象

class ImageFileLeaf extends AbstractFileComponent {
    public ImageFileLeaf(String name) {
        super(name);
    }
    @Override
    public void add(AbstractFileComponent component) {
        throw new NotImplementedException(this.getClass() + " not implemented this method");
    }
    @Override
    public void remove(AbstractFileComponent component) {
        throw new NotImplementedException(this.getClass() + " not implemented this method");
    }
    @Override
    public void killVirus(int depth) {
        printDepth(depth);
        System.out.println("图片文件 [" + name + "]杀毒");
    }
}
class TextFileLeaf extends AbstractFileComponent {
    public TextFileLeaf(String name) {
        super(name);
    }
    @Override
    public void add(AbstractFileComponent component) {
        throw new NotImplementedException(this.getClass() + " not implemented this method");
    }
    @Override
    public void remove(AbstractFileComponent component) {
        throw new NotImplementedException(this.getClass() + " not implemented this method");
    }
    @Override
    public void killVirus(int depth) {
        printDepth(depth);
        System.out.println("文本文件 [" + name + "]杀毒");
    }
}
class VideoFileLeaf extends AbstractFileComponent {
    public VideoFileLeaf(String name) {
        super(name);
    }
    @Override
    public void add(AbstractFileComponent component) {
        throw new NotImplementedException(this.getClass() + " not implemented this method");
    }
    @Override
    public void remove(AbstractFileComponent component) {
        throw new NotImplementedException(this.getClass() + " not implemented this method");
    }
    @Override
    public void killVirus(int depth) {
        printDepth(depth);
        System.out.println("视频文件 [" + name + "]杀毒");
    }
}

容器对象: 定义有分支节点的行为, 用来存储子部件, 实现与子部件有关的操作:

public class FolderFileComposite extends AbstractFileComponent {
    private List<AbstractFileComponent> components = new LinkedList<>();
    public FolderFileComposite(String name) {
        super(name);
    }
    @Override
    public void add(AbstractFileComponent component) {
        components.add(component);
    }
    @Override
    public void remove(AbstractFileComponent component) {
        components.remove(component);
    }
    @Override
    public void killVirus(int depth) {
        printDepth(depth);
        System.out.println("目录 [" + name + "]杀毒");
        for (AbstractFileComponent component : components) {
            component.killVirus(depth + 2);
        }
    }
}

客户端

public class Client {
    @Test
    public void client() {
        ImageFileLeaf image = new ImageFileLeaf("九寨沟.jpg");
        VideoFileLeaf video = new VideoFileLeaf("龙门飞甲.rmvb");
        TextFileLeaf text = new TextFileLeaf("解忧杂货店.txt");
        FolderFileComposite home = new FolderFileComposite("/home");
        home.add(image);
        home.add(video);
        home.add(text);
        FolderFileComposite root = new FolderFileComposite("/");
        root.add(home);
        root.add(new TextFileLeaf("/authorized_keys"));
        root.add(new FolderFileComposite("/etc"));
        root.killVirus(0);
    }
}
posted @ 2020-12-29 07:03  EvanMeetTheWorld  阅读(34)  评论(0)    收藏  举报