博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式-组合模式(Composite Pattern)
阅读量:5212 次
发布时间:2019-06-14

本文共 3664 字,大约阅读时间需要 12 分钟。

本文由原创,转载请注明出处: 

 

前置技能:认识数据结构中的树形结构。

 

组合模式简介

组合模式是将对象组合成树形结构以表示“部分-整体”的层次结构,每一个节点可以是叶子节点也可以使包含一堆子节点的中间节点,而且所有的节点都有同样的接口,用户在使用的时候无需区分节点类型,也就是可以将整个结构的任意部分当成“整体”来处理,这就是组合模式带来的方便。

 

组合模式的定义和基本结构

定义:将对象组合成树形结构以表示“部分-整体”的层次结构,并且为不同类型的节点提供完全相同的接口,让用户可以将整个结构的任意部分当成“整体”来处理。

 

一张来自《Head First》的结构图

 

Client:用户类,通过Component操作组合模式中的节点。

Component:组合模式中树状结构的每一个节点都要实现的接口,提供基本操作。

Leaf:树状结构中的叶子节点。

Composite:树状结构中的非叶子结点。

 

注意:我们可以看到,Component接口中有很多方法只适合于Composite而不适合Leaf,所以在Leaf中我们需要做好相应的处理工作,来让使用者感受不到差异的同时又不产生运行错误或者逻辑错误,如leaf没有孩子,我们可以让getChild方法直接抛出异常,或者返回null,一切都要结合实际使用背景来设计合适的处理逻辑。

 

一个简单的实例(java)

我们就实现一个纯的结构吧,每一个节点都包含一个字符串,Composite节点包含子节点,每个节点都可以打印自己的字符串,也可以一并打印自己所有子节点的字符串。

首先我们要定义一个Component。

1 public abstract class Component{ 2     private String s; 3     public Component(String s){ 4         this.s=s; 5     } 6     public String getString() { 7         return s; 8     } 9     public void print() {10         System.out.println(getString());11     }12     public abstract void printAll();13     public abstract void remove(Component s);14     public void add(Component s) {15         new UnsupportedOperationException();16     }17     public Component getChild(int i) {18         new UnsupportedOperationException();19         return null;20     }21 }

 

然后我们实现MyComposite类,这里储存子节点借用了ArrayList。

1 import java.util.ArrayList; 2 public class MyComposite extends Component { 3     private ArrayList
list; 4 public MyComposite(String s) { 5 super(s); 6 list=new ArrayList
(); 7 } 8 @Override 9 public void printAll() {10 System.out.println(getString()+"---------------"+"start");11 for(Component c:list)12 c.printAll();13 System.out.println(getString()+"---------------"+"end");14 }15 @Override16 public void add(Component s) {17 list.add(s);18 }19 @Override20 public void remove(Component s) {21 if(!list.remove(s)){22 for(Component c:list)23 c.remove(s);24 }25 }26 @Override27 public Component getChild(int i) {28 if(i

 

然后实现MyLeaf,这个相对简单。

1 public class MyLeaf extends Component { 2     public MyLeaf(String s) { 3         super(s); 4     } 5     public void printAll() { 6         print(); 7     } 8     @Override 9     public void remove(Component s) {10     }11 }

 

然后是测试类。

1 public class Test { 2     public static void main(String[] args) { 3         Component root=new MyComposite("1-root"); 4         root.add(new MyLeaf("2-1-Leaf")); 5         root.add(new MyComposite("2-2-Composite")); 6         Component r=new MyComposite("3-1-composite"); 7         root.getChild(1).add(r); 8         root.getChild(1).add(new MyLeaf("3-2-leaf")); 9         root.getChild(1).add(new MyLeaf("3-3-leaf"));10         11         root.getChild(1).getChild(0).add(new MyLeaf("4-1-leaf"));12         Component r2=new MyLeaf("4-2-leaf");13         root.getChild(1).getChild(0).add(r2);14         root.getChild(1).getChild(0).add(new MyLeaf("4-3-leaf"));15         root.getChild(1).getChild(0).add(new MyLeaf("4-4-leaf"));16         root.printAll();17         System.out.print("**************************************");18         root.print();19         root.remove(r2);20         root.printAll();21         System.out.print("**************************************");22         root.print();23         root.remove(r);24         root.printAll();25         System.out.print("**************************************");26         root.print();27     }28 }

 

输出如下:

 

小结:这个模式理解起来并不困难,重点在于了解树形结构,然后掌握递归调用的写法,剩下的就相当简单了。

 

组合模式到此结束,♪(^∇^*)

 

参考资料:《Head First 设计模式》。

 

转载于:https://www.cnblogs.com/coffeeSS/p/5698752.html

你可能感兴趣的文章
嵌入式Linux要学哪些东西?你真的造吗?
查看>>
linux后台运行之screen和nohup
查看>>
决策树算法(ID3)
查看>>
神经网络与BP神经网络
查看>>
.net设计模式 迪米特法则
查看>>
C语言 字符串处理函数
查看>>
leetcode 111. Minimum Depth of Binary Tree
查看>>
2007-11-9前琐碎事情
查看>>
Java向PostgreSQL发送prepared statement 与 libpq 向PostgreSQL发送prepared statement之比较:...
查看>>
GNU make manual 翻译( 九十七)
查看>>
TortoiseSVN的bin目录中没有svn.exe
查看>>
iOS开发运行报错、常见问题
查看>>
Codeforces 1063D Candies for Children
查看>>
Codeforces 295A Greg and Array
查看>>
移动操作系统原理与实践 123
查看>>
基础总结篇之二:Activity的四种launchMode
查看>>
免费 PSD 素材:25个全新的界面设计资源
查看>>
Perfect Scrollbar – 完美的 jQuery 滚动条插件
查看>>
Flexslider - 响应式的 jQuery 内容滚动插件
查看>>
赞!15个来自 CodePen 的酷炫 CSS 动画效果
查看>>