组合模式是将对象组合成树形结构以表示 “部分-整体” 的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
一、类图
组合模式包含了如下几个角色:
- 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); } }
……更多设计模式的内容,可以访问Refactoring.Guru