Java设计模式--组合模式【Composite Pattern】
2017-08-24 09:57
661 查看
最近看网络新闻,有许多讲儿女不养老的问题,多数都是由于老人有儿有女,偏又特别疼惜儿子,对闺女无限索取,导致儿子长大后自私自利,女儿心中愤愤不平,谁都不想履行赡养父母的义务。每每看到此类新闻 ,无比痛心。根深蒂固的封建思想,重男轻女在我们大中华,特别是农村以及偏远地区,无比猖獗。就拿家族族谱来说,许多姓氏追根溯源,都是从很久很久以前传承下来的。怎么传承呢?就是记入族谱。当然,如果记入族谱后,有人做了伤风败俗违反族规的事情,那么就要从族谱中除名了。很小的时候,我妈妈说,我们章氏也是有族谱的家族,族谱只记录可以传宗接代的男丁,可以延续章家香火,闺女那是没有资格入族谱的,因为闺女迟早要嫁人,是”别人家的“,我弟弟呢早就入了章家族谱,那一辈刚好是”茂“字辈,所以取名叫”章茂普“,当然这只是入族谱的名字,我弟弟早就改名成家立业了。。。
那么就来说一说这个章氏族谱,我翻了翻家族辈分排行,将前几代的族谱大概整理如下:
相信大家对这个族谱不陌生,这是一个典型的树状结构,我们今天的任务就是要把这个树状结构实现出来,并且还要让它可以自上而下,自下而上地遍历,那么就来稍作分析。从这个树状结构上看,有两种节点:有分支的节点(蓝色节点)和无分支的节点(橙色节点),它们的区别就是蓝色节点有子嗣,可以延续香火,而橙色节点很不幸,没有下一代,不能完成家族伟大的使命。这两种节点除了是否有子嗣问题,其他的属性,不如名字啊,第几代啊,父亲啊,都是一样的。那么我们是否可以将相同的信息提取出来,统一放到抽象类中,然后让这两种节点继承此类,另外给有子嗣的节点添加额外的子嗣遍历等方法,按照这个思路,看我的设计图:
这个呢,就是组合模式。
所谓组合模式,就是将对象以树形结构组织起来,以达成“部分-整体” 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性。
组合模式的优点有哪些呢?第一个优点只要是树形结构,就要考虑使用组合模式,这个一定记住,只要是要体现局部和整体的关系的时候,而且这种关系还可能比较深,考虑一下组合模式吧。
下面我们就来实现上述的“章氏族谱”。首先,我们定义一个统一的抽象父类:
运行结果如下:
从上述Test类可以看出,组合模式有一个非常明显的缺点,如下:
组合模式在项目中到处都有,比如电脑的文件系统,比如菜单导航,比如XML文件。。。
所以组合模式的应用非常广泛,那么我们来总结下组合模式的构成要素:
抽象构件角色(component):是组合中的对象的抽象类接口,在适当的情况下,实现所有类共有接口的默认行为,声明一个接口用于访问和管理Component子部件,用来管理所有的子对象。
树叶构件角色(Leaf):在组合树中表示叶节点对象,叶节点没有子节点。并在组合中定义图元对象的行为。
树枝构件角色(Composite):定义有子部件的那些部件的行为,存储子部件,且在Component接口中实现与子部件有关的操作。
客户角色(Client):通过component接口操纵组合部件的对象。
源码下载:http://download.csdn.net/download/pelifymeng2/9994734
那么就来说一说这个章氏族谱,我翻了翻家族辈分排行,将前几代的族谱大概整理如下:
相信大家对这个族谱不陌生,这是一个典型的树状结构,我们今天的任务就是要把这个树状结构实现出来,并且还要让它可以自上而下,自下而上地遍历,那么就来稍作分析。从这个树状结构上看,有两种节点:有分支的节点(蓝色节点)和无分支的节点(橙色节点),它们的区别就是蓝色节点有子嗣,可以延续香火,而橙色节点很不幸,没有下一代,不能完成家族伟大的使命。这两种节点除了是否有子嗣问题,其他的属性,不如名字啊,第几代啊,父亲啊,都是一样的。那么我们是否可以将相同的信息提取出来,统一放到抽象类中,然后让这两种节点继承此类,另外给有子嗣的节点添加额外的子嗣遍历等方法,按照这个思路,看我的设计图:
这个呢,就是组合模式。
所谓组合模式,就是将对象以树形结构组织起来,以达成“部分-整体” 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性。
组合模式的优点有哪些呢?第一个优点只要是树形结构,就要考虑使用组合模式,这个一定记住,只要是要体现局部和整体的关系的时候,而且这种关系还可能比较深,考虑一下组合模式吧。
下面我们就来实现上述的“章氏族谱”。首先,我们定义一个统一的抽象父类:
package com.pattern.composite; /** * 章氏家族族谱 * @author * */ public abstract class Family { protected String name;//姓名 protected int depth;//第几代 protected Family parent;//父亲是谁 public String getName() { return name; } public int getDepth() { return depth; } public void setParent(Family parent) { this.parent = parent; } public Family getParent() { return parent; } public Family(String name, int depth) { this.name = name; this.depth = depth; } }由于子节点有两种,一种是有后代的节点,一种是没有后代的节点。我们将两者分别实现:
package com.pattern.composite; import java.util.ArrayList; import java.util.List; /** * 有下一代的子族 * @author * */ public class BranchFamily extends Family { private List<Family> familyChildren=new ArrayList<Family>();//子族族谱,延续香火,生生不息 public BranchFamily(String name, int depth) { super(name, depth); } public void addChild(Family famlily) {//将儿子们记入族谱 familyChildren.add(famlily); famlily.setParent(this); } public void remove(Family famlily) {//做了伤风败俗的事,从族谱中除名 familyChildren.remove(famlily); } public List<Family> getChildren() {//看看都有哪些儿子啊 return familyChildren; } }
package com.pattern.composite; /** * 没有下一代的子族 * @author * */ public class LeafFamily extends Family{ public LeafFamily(String name, int depth) { super(name, depth); } }组合模式,最主要的就是对树状结构迭代遍历。这里我们写测试类中,可以从根节点自上而下遍历,也可以给出任意子节点,自下而上遍历出所有的父节点。测试类如下:
package com.pattern.composite; import java.util.List; public class Test { public static void main(String[] args){ BranchFamily f1=new BranchFamily("章积才",1);//章氏第一代族谱 老祖宗 BranchFamily f20=new BranchFamily("章德华",2);//章氏第二代族谱 f1.addChild(f20);//设立父子关系 LeafFamily f21=new LeafFamily("章德渊",2);//章氏第二代族谱 无后 f1.addChild(f21); BranchFamily f22=new BranchFamily("章德扬",2);//章氏第二代族谱 f1.addChild(f22); BranchFamily f30=new BranchFamily("章嗣元",3);//章氏第三代族谱 f20.addChild(f30); BranchFamily f31=new BranchFamily("章嗣繁",3);//章氏第三代族谱 f20.addChild(f31); LeafFamily f32=new LeafFamily("章嗣义",3);//章氏第三代族谱 无后 f22.addChild(f32); LeafFamily f33=new LeafFamily("章嗣充",3);//章氏第三代族谱 无后 f22.addChild(f33); BranchFamily f34=new BranchFamily("章嗣戴",3);//章氏第三代族谱 f22.addChild(f34); BranchFamily f35=new BranchFamily("章嗣卿",3);//章氏第三代族谱 f22.addChild(f35); LeafFamily f40=new LeafFamily("章荣华",4);//章氏第四代族谱 无后 f30.addChild(f40); LeafFamily f41=new LeafFamily("章荣兴",4);//章氏第四代族谱 无后 f31.addChild(f41); BranchFamily f42=new BranchFamily("章荣盛",4);//章氏第四代族谱 f34.addChild(f42); BranchFamily f43=new BranchFamily("章荣宣",4);//章氏第四代族谱 f34.addChild(f43); LeafFamily f44=new LeafFamily("章荣家",4);//章氏第四代族谱 无后 f35.addChild(f44); BranchFamily f45=new BranchFamily("章荣起",4);//章氏第四代族谱 f35.addChild(f45); System.out.println("----------从根节点向下遍历------------------"); System.out.println(getFamilyChildrenInfo(f1));//从祖宗开始向下找,找出族谱的所有信息 System.out.println("----------从任意节点向上遍历------------------"); 4000 System.out.println(getFamilyParentInfo(f42));//给出族谱任意一人(这里是章荣盛),向上找出他所有的父族信息 } /** * 从根节点向下遍历:找出所有的子族信息 * @param root * @return */ public static String getFamilyChildrenInfo(BranchFamily root){ List<Family> familyChildren=root.getChildren(); String info=""; for(Family f:familyChildren){ if(f instanceof LeafFamily){ info=info+f.getName()+",章氏族谱第"+f.getDepth()+"代\n"; }else{ info=info+f.getName()+",章氏族谱第"+f.getDepth()+"代\n子族:"+getFamilyChildrenInfo((BranchFamily)f); } } return info; } /** * 从任意子节点向上遍历:找出所有的父族信息 * @param f * @return */ public static String getFamilyParentInfo(Family f){ String info=""; if(f.getParent()==null){ info=info+f.getName()+",章氏族谱第"+f.getDepth()+"代,已经是祖宗啦!没有上一代\n"; }else{ info=info+f.getName()+",章氏族谱第"+f.getDepth()+"代,\n父族:"+f.getParent().getName()+",\n"+getFamilyParentInfo(f.getParent())+"\n"; } return info; } }
运行结果如下:
从上述Test类可以看出,组合模式有一个非常明显的缺点,如下:
LeafFamily f44=new LeafFamily("章荣家",4);//章氏第四代族谱 无后 BranchFamily f45=new BranchFamily("章荣起",4);//章氏第四代族谱发现什么问题了吗?直接使用了实现类!这个在面向接口编程上是很不恰当的,这个在使用的时候要考虑清楚。
组合模式在项目中到处都有,比如电脑的文件系统,比如菜单导航,比如XML文件。。。
所以组合模式的应用非常广泛,那么我们来总结下组合模式的构成要素:
抽象构件角色(component):是组合中的对象的抽象类接口,在适当的情况下,实现所有类共有接口的默认行为,声明一个接口用于访问和管理Component子部件,用来管理所有的子对象。
树叶构件角色(Leaf):在组合树中表示叶节点对象,叶节点没有子节点。并在组合中定义图元对象的行为。
树枝构件角色(Composite):定义有子部件的那些部件的行为,存储子部件,且在Component接口中实现与子部件有关的操作。
客户角色(Client):通过component接口操纵组合部件的对象。
源码下载:http://download.csdn.net/download/pelifymeng2/9994734
相关文章推荐
- java设计模式之组合模式
- Java设计模式偷跑系列(十二)组合模式建模和实现
- Java设计模式之迭代器模式和组合模式
- JAVA设计模式--组合模式
- JAVA设计模式(组合模式)
- Java/Android 设计模式系列(12)--组合模式
- Java设计模式—组合模式
- Java设计模式之结构型模式-组合模式(Composite)
- JAVA设计模式之组合模式
- java设计模式-组合模式
- Java语言设计模式之组合模式(Composite)
- Java设计模式之组合模式
- 浅谈Java设计模式(十一)组合模式(Composite)
- java设计模式(八)---组合模式
- java设计模式_组合模式
- java设计模式5.组合模式、门面模式、享元模式、桥接模式
- JAVA设计模式(11) —<结构型>组合模式(Composite)