树状结构在实际项目应用中非常广泛,人事管理就是一个典型的树状结构。
今天的任务就是把树状结构实现出来,并且把它遍历一遍。
有两种节点:有分支的节点(如研发部经理)和无分支的节点,总经理叫做根节点(XML中有个根节点root),类似研发部经理有分支的节点叫做树枝节点,类似员工A的无分支节点叫做树叶节点。
接口的作用是什么?定义共性。抽象类中,可以有实现的方法。
抽象类:
package com.teng.pattern.impl;
import java.util.ArrayList;
import com.teng.pattern.abs.Corp;
/**
* 分支节点,管理者
* <br>创建日期:2016年7月30日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class Branch extends Corp {
/**
* 管理者下面的员工
*/
private ArrayList<Corp> subordinateList = new ArrayList<Corp>();
/**
* 构造器
* @param _name n
* @param _position p
* @param _salary s
*/
public Branch(String _name, String _position, int _salary) {
super(_name, _position, _salary);
}
/**
* 管理者添加手下员工
* @since 1.0
* @param corp
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年7月30日 上午11:22:57
*/
public void addSubordinate(Corp corp){
corp.setParent(this);
this.subordinateList.add(corp);
}
/**
* 获取管理者手下的员工
* @since 1.0
* @return
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年7月30日 上午11:24:03
*/
public ArrayList<Corp> getSubordinate(){
return this.subordinateList;
}
}
两个具体实现:
package com.teng.pattern.impl;
import com.teng.pattern.abs.Corp;
/**
* 叶子节点,员工
* <br>创建日期:2016年7月30日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class Leaf extends Corp {
/**
* 构造器
* @param _name n
* @param _position p
* @param _salary s
*/
public Leaf(String _name, String _position, int _salary) {
super(_name, _position, _salary);
}
}
package com.teng.pattern.impl;
import java.util.ArrayList;
import com.teng.pattern.abs.Corp;
/**
* 分支节点,管理者
* <br>创建日期:2016年7月30日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class Branch extends Corp {
/**
* 管理者下面的员工
*/
private ArrayList<Corp> subordinateList = new ArrayList<Corp>();
/**
* 构造器
* @param _name n
* @param _position p
* @param _salary s
*/
public Branch(String _name, String _position, int _salary) {
super(_name, _position, _salary);
}
/**
* 管理者添加手下员工
* @since 1.0
* @param corp
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年7月30日 上午11:22:57
*/
public void addSubordinate(Corp corp){
corp.setParent(this);
this.subordinateList.add(corp);
}
/**
* 获取管理者手下的员工
* @since 1.0
* @return
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年7月30日 上午11:24:03
*/
public ArrayList<Corp> getSubordinate(){
return this.subordinateList;
}
}
组装类:
package com.teng.pattern.impl;
import java.util.ArrayList;
import com.teng.pattern.abs.Corp;
/**
* 组合模式
* <br>创建日期:2016年7月30日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class Client {
/**
* 主方法
* @since 1.0
* @param args
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年7月30日 上午11:27:09
*/
public static void main(String[] args) {
//首先组装一个组织结构
Branch ceo = compositeCorpTree();
//首先把CEO的信息打印出来
System.out.println(ceo.getInfo());
//展示所有员工的信息
System.out.println(getTreeInfo(ceo));
}
/**
* 组装
* @since 1.0
* @return
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年7月30日 下午12:11:58
*/
public static Branch compositeCorpTree(){
//首先产生总经理CEO
Branch root = new Branch("王大麻子","总经理",100000);
//三个部门经理产生出来
Branch developDep = new Branch("刘大","研发部门经理",10000);
Branch salesDep = new Branch("马二","销售部门经理",20000);
Branch financeDep = new Branch("赵三","财务部经理",30000);
//三个小组长
Branch firstDevGroup = new Branch("杨三","开发一组组长",5000);
Branch secondDevGroup = new Branch("吴大","开发二组组长",6000);
//所有员工
Leaf a = new Leaf("a","开发人员",2000);
Leaf b = new Leaf("b","开发人员",2000);
Leaf c = new Leaf("c","开发人员",2000);
Leaf d = new Leaf("d","开发人员",2000);
Leaf e = new Leaf("e","开发人员",2000);
Leaf f = new Leaf("f","开发人员",2000);
Leaf h = new Leaf("h","销售人员",5000);
Leaf i = new Leaf("i","销售人员",4000);
Leaf j = new Leaf("j","财务人员",5000);
Leaf k = new Leaf("k","CEO秘书",8000);
Leaf zhengLaoLiu = new Leaf("郑老六","研发部副经理",20000);
//开始组装
//CEO下有三个部门经理和一个秘书
root.addSubordinate(k);
root.addSubordinate(developDep);
root.addSubordinate(salesDep);
root.addSubordinate(financeDep);
//研发部经理
developDep.addSubordinate(zhengLaoLiu);
developDep.addSubordinate(firstDevGroup);
developDep.addSubordinate(secondDevGroup);
//两个开发小组
firstDevGroup.addSubordinate(a);
firstDevGroup.addSubordinate(b);
firstDevGroup.addSubordinate(c);
secondDevGroup.addSubordinate(d);
secondDevGroup.addSubordinate(e);
secondDevGroup.addSubordinate(f);
//销售部人员情况
salesDep.addSubordinate(h);
salesDep.addSubordinate(i);
//最后一个财务
financeDep.addSubordinate(j);
return root;
}
/**
* 遍历管理者及其手下员工
* @since 1.0
* @param branch b
* @return
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年7月30日 下午12:11:26
*/
public static String getTreeInfo(Branch branch){
ArrayList<Corp> subordinateList = new ArrayList<Corp>();
subordinateList = branch.getSubordinate();
String info = "";
for(Corp corp : subordinateList){
if(corp instanceof Leaf){
Leaf e = (Leaf)corp;
info += e.getInfo() + "\n";
}else{
Branch b = (Branch)corp;
info += b.getInfo() + "\n";
info += getTreeInfo(b);
}
}
return info;
}
}
上面讲到的就是组合模式(也叫合成模式),有时又叫部分-整体模式(Part-Whole),主要是用来描述整体与部分的关系,用的最多的地方就是树形结构。
说说组合模式的几个角色:
抽象构建角色(Component):定义参加组合的对象的共有方法和属性,可以定义一些默认的行为或属性;比如我们例子中的getInfo就封装到了抽象类中。
叶子构件(Leaf): 叶子对象,其下再也没有其他的分支。
树枝构件(Composite):树枝对象,它的作用是组合树枝节点和叶子节点;
安全模式是把树枝节点和树叶节点彻底分开,树枝节点单独拥有用来组合的方法,这种方法比较安全,我们例子就用安全模式。