被说了很多遍的设计模式---组合模式
来源:互联网 发布:朝鲜核爆东北 知乎 编辑:程序博客网 时间:2024/05/02 06:10
[把你的理性思维慢慢变成条件反射]
本文,我们讲介绍组合模式,文章主题结构与上文一致。惯例,先来看看我们示例工程的环境:
操作系统:win7 x64
其他软件:eclipse mars,jdk7
-------------------------------------------------------------------------------------------------------------------------------------
经典问题:
文件系统的目录结构,公司或政府部门的组织结构等具有树形递归关系的抽象组织结构。
思路分析:
要点一:每一级都可作为一个完整的最小树型结构。
要点二:每一级的外在表现类似,具有屏蔽层次结构的功能。如:文件系统不同级别的目录都具有相同的表现形式。分级行政办公组织结构中的相同部门设置。
要点三:对软件实现而言,需要尽可能的提高代码复用度。
示例工程:
组合模式模板代码【本例我们先展示模板代码,稍后演示一个具体的示例】
创建Component.java文件,具体内容如下:
package com.csdn.ingo.gof_Composite;public abstract class Component{protected String name;public Component(String name){this.name = name;}public abstract void add(Component c);public abstract void remove(Component c);public abstract void display(int depth);}创建Composite.java文件,具体内容如下:
package com.csdn.ingo.gof_Composite;import java.util.ArrayList;import java.util.List;public class Composite extends Component {private List<Component> children = new ArrayList<Component>();public Composite(String name) {super(name);// TODO Auto-generated constructor stub}@Overridepublic void add(Component c) {// TODO Auto-generated method stubchildren.add(c);}@Overridepublic void remove(Component c) {// TODO Auto-generated method stubchildren.remove(c);}@Overridepublic void display(int depth) {// TODO Auto-generated method stubSystem.out.println("-"+name);for(Component c:children){c.display(depth+1);}}}创建Leaf.java文件,具体内容如下:
package com.csdn.ingo.gof_Composite;public class Leaf extends Component{public Leaf(String name) {super(name);}@Overridepublic void add(Component c) {// TODO Auto-generated method stubSystem.out.println("cannot add to leaf");}@Overridepublic void remove(Component c) {System.out.println("cannot remove from a leaf");}@Overridepublic void display(int depth) {// TODO Auto-generated method stubSystem.out.println(new String("----")+"depth:"+depth+"name:"+name);}}创建Window.java文件,具体内容如下:
package com.csdn.ingo.gof_Composite;public class Window {public static void main(String[] args) {Composite root = new Composite("root");root.add(new Leaf("Leaf A"));root.add(new Leaf("Leaf B"));Composite comp = new Composite("ComposteX");comp.add(new Leaf("Leaf XA"));comp.add(new Leaf("Leaf XB"));root.add(comp);Composite comp2 = new Composite("ComposteXY");comp2.add(new Leaf("Leaf XYA"));comp2.add(new Leaf("Leaf XYB"));comp.add(comp2);root.add(new Leaf("Leaf C"));Leaf l = new Leaf("Leaf D");root.add(l);root.remove(l);root.display(1);}}
【上面的代码直接看的话,可能有难度。先把代码提供给各位看官是希望现将代码运行起来,观察结果。下面我们介绍相关的概念与原理】
模式总结:
组合模式结构图:
组合模式:
将对象组合成属性结构以表示“部分--整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
组成部分:
Component:抽象构件。可以是接口或者抽象类。其中包含leaf与composite公共接口的声明。如,增删改功能。
Leaf:叶子节点。其实就是最后一级节点,其下不能再有任何形式的impl或extend关系。其本身必须实现Component中定义的内容。
Composite:容器组件。是相对于Leaf定义的。其下还能够挂载其他的节点(可以是Leaf或Composite)。其中,可以通过递归实现对子部件的调用。
【以上,可以类比文件系统中的文件夹,文件夹可以包含文件或文件夹,文件本身不能包含其他文件或文件夹】
特别提示:上面的模板代码,在leaf与Composite中都包含了add和remove方法。但事实上,只有Composite的中的方法才是有效的。
实际场景用例:
需求描述:
公司包括:子公司,人力,研发,财务。子公司包括:子公司(可选的),人力,研发,财务。等等。
示例代码:
创建Company.java文件,具体内容如下:
package com.csdn.ingo.gof_Composite.one;public abstract class Company{protected String name;public Company(String name){this.name = name;}public abstract void add(Company c);public abstract void remove(Company c);public abstract void display(int depth);public abstract void lineOfDuty();}创建ConcreteCompany.java文件,具体内容如下:
package com.csdn.ingo.gof_Composite.one;import java.util.ArrayList;import java.util.List;public class ConcreteCompany extends Company {private List<Company> children = new ArrayList<Company>();public ConcreteCompany(String name) {super(name);// TODO Auto-generated constructor stub}@Overridepublic void add(Company c) {// TODO Auto-generated method stubchildren.add(c);}@Overridepublic void remove(Company c) {// TODO Auto-generated method stubchildren.remove(c);}@Overridepublic void display(int depth) {// TODO Auto-generated method stubSystem.out.println("-"+name);for(Company c:children){c.display(depth);}}@Overridepublic void lineOfDuty() {// TODO Auto-generated method stubfor(Company c:children){c.lineOfDuty();}}}创建FinanceDepartment.java文件,具体内容如下:
package com.csdn.ingo.gof_Composite.one;public class FinanceDepartment extends Company{public FinanceDepartment(String name) {super(name);}@Overridepublic void add(Company c) {// TODO Auto-generated method stub}@Overridepublic void remove(Company c) {// TODO Auto-generated method stub}@Overridepublic void display(int depth) {// TODO Auto-generated method stubSystem.out.println("----"+name);}@Overridepublic void lineOfDuty() {// TODO Auto-generated method stubSystem.out.println("finance duty:"+name);}}创建HRDepartment.java文件,具体内容如下:
package com.csdn.ingo.gof_Composite.one;public class HRDepartment extends Company{public HRDepartment(String name) {super(name);}@Overridepublic void add(Company c) {// TODO Auto-generated method stub}@Overridepublic void remove(Company c) {// TODO Auto-generated method stub}@Overridepublic void display(int depth) {// TODO Auto-generated method stubSystem.out.println("----"+name);}@Overridepublic void lineOfDuty() {// TODO Auto-generated method stubSystem.out.println("HR duty:"+name);}}
创建Window.java文件,具体内容如下:
package com.csdn.ingo.gof_Composite.one;public class Window {public static void main(String[] args) {;Company root = new ConcreteCompany("总公司");root.add(new HRDepartment("总公司人力资源部"));root.add(new FinanceDepartment("总公司财务部"));ConcreteCompany comp1 = new ConcreteCompany("上海分公司");comp1.add(new HRDepartment("上海分公司人力资源部"));comp1.add(new FinanceDepartment("上海分公司财务部"));root.add(comp1);ConcreteCompany comp2 = new ConcreteCompany("南京分公司");comp2.add(new HRDepartment("南京分公司人力资源部"));comp2.add(new FinanceDepartment("南京分公司财务部"));root.add(comp2);root.display(1);root.lineOfDuty();}}注:与模板代码对比,这里root对象也可以是抽象类Company。但,具体组织需要特别声明为具体实现。
模式扩展:
在上文中,我们说只有composite中的add和remove是有效的。
事实上,这些方法的设置在组合模式中成为透明组合模式,安全组合模式。即,在透明组合模式中,这些方法不区分leaf与composite。具体应用时可以通过返回值的变化或异常信息返回。而,安全组合模式要求父类不提供该方法的声明,而是由composite进行声明,这样在Window主类中就需要区别声明leaf与composite两个对象。
反思:
应用场景:
- 具有整体与部分的树形层次结构关系时,希望通过相同的结构屏蔽层次之间的差异性。
- 不同树形层次的功能具有类似性,并且希望达到重用的目的。
- 层次关系是不固定的,需要按照需求修改。
优点:
- 组合模式能够清楚的定义出复杂的关系。并且向客户端屏蔽了这种复杂与差异性。
- 客户端使用树形结构中的任何一个关系,可以通过一个统一的接口。有效减少客户端的依赖程度。
- 对树形结构的调整非常方便。而树形结构本身可能是非常复杂的。
缺点:
- 对于树形层次的约束不够。如,在组织关系处理中,子公司内不需要设置***部,但由于没有强制的约束条件,客户端可以随意修改。
-------------------------------------------------------------------------------------------------------------------------------------
至此,被说了很多遍的设计模式---组合模式 结束
参考资料:
图书:《大话设计模式》
其他博文:http://blog.csdn.NET/lovelion/article/details/7563445
- 被说了很多遍的设计模式---组合模式
- 被说了很多遍的设计模式---策略模式
- 被说了很多遍的设计模式---装饰模式
- 被说了很多遍的设计模式---代理模式
- 被说了很多遍的设计模式---原型模式
- 被说了很多遍的设计模式---外观模式
- 被说了很多遍的设计模式---观察者模式
- 被说了很多遍的设计模式---状态模式
- 被说了很多遍的设计模式---适配器模式
- 被说了很多遍的设计模式---备忘录模式
- 被说了很多遍的设计模式---迭代器模式
- 被说了很多遍的设计模式---命令模式
- 被说了很多遍的设计模式---访问者模式
- 被说了很多遍的设计模式---简单工厂模式
- 被说了很多遍的设计模式---工厂方法模式
- 被说了很多遍的设计模式---模板方法模式
- 被说了很多遍的设计模式---建造者模式
- 被说了很多遍的设计模式---抽象工厂模式
- 通俗易懂讲解happens-before原则
- [笔记]CTR预估中的贝叶斯平滑方法及其代码实现
- JSP取得绝对路径
- bzoj 2500 幸福的道路 动态规划+单调栈
- poj1442——Black Box(优先队列)
- 被说了很多遍的设计模式---组合模式
- Spring中的计时器StopWatch
- Javase易错之方法重写 子类方法返回值应比父类返回值更小或相等
- 有用的工具
- 策略模式
- hrbust 2181
- 让 sudo 会话时间随心所欲
- linux 用ld链接nasm编译的elf格式的.o文件报错
- Android多线程下载