组合模式
来源:互联网 发布:指向二维数组的指针 编辑:程序博客网 时间:2024/05/16 09:43
组合模式
标签 : Java与设计模式
组合模式: 将对象组合成树形结构以表示‘部分-整体’的层次结构, 使得用户对单个对象和组合对象的使用具有一致性.
- 解析
- 组合模式描述了如何将容器和叶子节点进行递归组合, 使用户在使用时可一致的对待容器和叶子, 为处理树形结构提供了完美的解决方案.
- 当容器对象的指定方法被调用时, 将遍历整个树形结构, 并执行调用. 整个过程递归处理.
(图片来源: 设计模式: 可复用面向对象软件的基础)
模式实现
案例: 杀毒软件
使对文件(Image/Text/Video/…)杀毒与对文件夹(Folder)的杀毒暴露统一接口.
Component
- 为组合模式中的对象声明接口, 在适当情况下, 实现所有类共有接口的默认行为.
- 声明一个接口用于访问和管理Component子组件.
/** * @author jifang * @since 16/8/24 上午10:19. */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);}
Leaf
- 叶子对象: 定义没有有分支节点的行为:
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 + "]杀毒"); }}
Composite
- 容器对象: 定义有分支节点的行为, 用来存储子部件, 实现与子部件有关的操作:
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); } }}
- Client
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); }}
上面的实现方式是透明方式: 直接在Component中声明
add()
/remove()
. 这样做的好处是叶节点和枝节点对于外界没有任何区别, 他们具有完全一致的行为接口. 但问题是对叶节点实现add()
/remove()
没有任何意义. 所以还有另一种实现方式安全方式, 也就是在Component中不去声明add()
/remove()
, 而是在Composite声明所有用来管理子类对象的方法, 不过由于不够透明, 所以叶节点与枝节点将不具有相同接口, 客户端调用需要作出相应判断, 带来了不便, 关于该问题的详细信息可参考: 组合模式(Composite)的安全模式与透明模式.
小结
- 组合模式定义了基本对象和组合对象的类层次结构, 基本对象可以被组合成更复杂的组合对象, 而这个组合对象又可以被组合, 这样不断地递归下去, 这样在客户代码中任何用到基本对象的地方都可以使用组合对象.
- 用户不用关心到底是处理一个叶节点还是处理一个枝节点, 也用不着为定义组合而写一些选择判断语句.
总的来说: 组合模式让用户可以一致地使用组合结构和单个对象.
- 场景
当需求中是体现部分与整体层次的结构时, 以及希望用户可以忽略组合对象与单个对象的不同, 统一地使用组合中的所有对象时, 就应该考虑使用组合模式了:- 操作系统资源管理器
- GUI容器视图
- XML文件解析
- OA系统中组织机构处理
- Junit单元测试框架
- TestCase(叶子)、TestUnite(容器)、Test接口(抽象)
- 参考
- 设计模式: 可复用面向对象软件的基础
- 大话设计模式
- 高淇讲设计模式
- JAVA设计模式十七–Composite(组合模式)
- 设计模式系列-组合模式
- 组合模式(Composite)的安全模式与透明模式
1 0
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 组合模式
- 神器gist
- js动态创建表格
- 实现表单的提交通过jquery的ajax
- ajax提交整个form表单
- Jquery通过Ajax方式来提交Form表单
- 组合模式
- jquery.form.js实现将form提交转为ajax方式提交的方法
- react-native-gradle-2.10-all.zip-下载慢
- 用exp_imp远程操作数据库,附帶Oracle数据导入导出imp/exp詳解
- android spinner下拉框组件使用
- Agile实践之Kanban工具: Wekan
- 记一次从库主机断电重启后同步故障处理
- 北京折叠——一部刚要开始就已经结束的科幻小说
- POJ 2000 Gold Coins(模拟)