组合器模式
组合器模式:将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和对组合对象的使用具有一致性。
角色:1.Leaf叶子构件:叶子对象,之下没有其它分支了,遍历的最小对象
2.Composite树枝构件:树枝对象。之下有其它节点。和叶子构成一整个树。
适用场景:树形菜单,文件夹等。
具体实现:一个公司里面有领导也有员工,领导管理着员工。从最高领导开始,到最下层的员工,构成一棵树。
通用实现(安全模式)
1.创建抽象公司员工类,即抽象构件
/**
* 抽象公司职员类
* 根节点,树枝,树叶都继承于此
* 也可使用接口
*/
public abstract class Corp {
//公司的每个人都有名字
private String name = "";
//公司的每个人都有职位
private String postion = "";
//公司的每个人都有薪水
private int salary = 0;
public Corp(String name,String postion,int salary){
this.name = name;
this.postion = postion;
this.salary = salary;
}
//获得自己信息
public String getInfo(){
String info = "";
info = "姓名:"+this.name;
info+=" 职位"+this.postion;
info+=" 薪水:"+this.salary;
return info;
}
}
2.创建领导类,即树枝类
/**
* 公司领导
* 树枝节点和根节点
* 之下还有节点
*/
public class Branch extends Corp{
//领导之下有哪些员工,即该节点之下有哪些节点
private List<Corp> list = new ArrayList<>();
public Branch(String name,String postion,int salary){
super(name,postion,salary);
}
//增加一个下属员工,即增加一个下层节点
public void add(Corp corp){
this.list.add(corp);
}
//查看自己有哪些下层节点
public List<Corp> getList(){
return this.list;
}
}
3.创建员工类,即树叶类
/**
* 公司底层员工
* 树叶节点
* 之下无节点
*/
public class Leaf extends Corp{
public Leaf(String name,String postion,int salary){
super(name,postion,salary);
}
}
4.创建场景测试类
/**
* 场景测试类
*/
public class Client {
public static void main(String[] args) {
//生成一些树枝
Branch ceo = new Branch("张三","总经理",1000000); //根节点
Branch ceo2 = new Branch("李四","产品经理",100000);
Branch ceo3 = new Branch("王五","人事经理",10000);
Branch ceo4 = new Branch("王六","人事副经理",10000);
//生成一些树叶
Leaf leaf1 = new Leaf("李十","产品员工",1000);
Leaf leaf2 = new Leaf("李十一","产品员工",1000);
Leaf leaf3 = new Leaf("王二十","人事员工",1000);
Leaf leaf4 = new Leaf("王三十","人事员工",1000);
//组装
ceo.add(ceo2);
ceo.add(ceo3);
ceo2.add(leaf1);
ceo2.add(leaf2);
ceo3.add(ceo4);
ceo3.add(leaf3);
ceo4.add(leaf4);
//先输出根节点的信息
System.out.println(ceo.getInfo());
getTree(ceo);
}
//从一个根节点递归遍历
public static void getTree(Branch branch){
List<Corp> list = branch.getList();
for (Corp c:list) {
if(c instanceof Leaf){
System.out.println(c.getInfo());
}
else{
System.out.println(c.getInfo());
getTree((Branch) c);
}
}
}
}
透明模式(即可把添加节点等操作也放入抽象构件。没有此操作的leaf节点在实现的时候就抛出错误。这样遍历时不需要类型转换,但是不安全)
1.修改抽象构件
/**
* 抽象公司职员类
* 根节点,树枝,树叶都继承于此
* 也可使用接口
*/
public abstract class Corp {
//公司的每个人都有名字
private String name = "";
//公司的每个人都有职位
private String postion = "";
//公司的每个人都有薪水
private int salary = 0;
//增加一个下属员工,即增加一个下层节点
public abstract void add(Corp corp);
//查看自己有哪些下层节点
public abstract List<Corp> getList();
public Corp(String name, String postion, int salary){
this.name = name;
this.postion = postion;
this.salary = salary;
}
//获得自己信息
public String getInfo(){
String info = "";
info = "姓名:"+this.name;
info+=" 职位"+this.postion;
info+=" 薪水:"+this.salary;
return info;
}
}
2.修改叶子节点
/**
* 公司底层员工
* 树叶节点
* 之下无节点
*/
public class Leaf extends Corp{
public Leaf(String name,String postion,int salary){
super(name,postion,salary);
}
@Deprecated //该注解表示此方法已经失效,调用从方法可能会抛出错误
public void add(Corp corp) {
throw new UnsupportedOperationException();
}
@Deprecated
public List<Corp> getList() {
throw new UnsupportedOperationException();
}
}
3.修改场景测试类
/**
* 场景测试类
*/
public class Client {
public static void main(String[] args) {
//生成一些树枝
Branch ceo = new Branch("张三","总经理",1000000); //根节点
Branch ceo2 = new Branch("李四","产品经理",100000);
Branch ceo3 = new Branch("王五","人事经理",10000);
Branch ceo4 = new Branch("王六","人事副经理",10000);
//生成一些树叶
Leaf leaf1 = new Leaf("李十","产品员工",1000);
Leaf leaf2 = new Leaf("李十一","产品员工",1000);
Leaf leaf3 = new Leaf("王二十","人事员工",1000);
Leaf leaf4 = new Leaf("王三十","人事员工",1000);
//组装
ceo.add(ceo2);
ceo.add(ceo3);
ceo2.add(leaf1);
ceo2.add(leaf2);
ceo3.add(ceo4);
ceo3.add(leaf3);
ceo4.add(leaf4);
//先输出根节点的信息
System.out.println(ceo.getInfo());
getTree(ceo);
}
//从一个根节点递归遍历
public static void getTree(Corp corp){
List<Corp> list = corp.getList();
for (Corp c:list) {
if(c instanceof Leaf){
System.out.println(c.getInfo());
}
else{
System.out.println(c.getInfo());
getTree(c);
}
}
}
}
向上遍历(增加父节点)
1.修改抽象构件
/**
* 抽象公司职员类
* 根节点,树枝,树叶都继承于此
* 也可使用接口
*/
public abstract class Corp {
//公司的每个人都有名字
private String name = "";
//公司的每个人都有职位
private String postion = "";
//公司的每个人都有薪水
private int salary = 0;
//增加父节点
private Corp parent = null;
//得到父节点
public Corp getParent() {
return parent;
}
//设置父节点
public void setParent(Corp parent) {
this.parent = parent;
}
public Corp(String name, String postion, int salary){
this.name = name;
this.postion = postion;
this.salary = salary;
}
//获得自己信息
public String getInfo(){
String info = "";
info = "姓名:"+this.name;
info+=" 职位"+this.postion;
info+=" 薪水:"+this.salary;
return info;
}
}
2.修改领导类,即树枝
/**
* 公司领导
* 树枝节点和根节点
* 之下还有节点
*/
public class Branch extends Corp{
//领导之下有哪些员工,即该节点之下有哪些节点
private List<Corp> list = new ArrayList<>();
public Branch(String name,String postion,int salary){
super(name,postion,salary);
}
//增加一个下属员工,即增加一个下层节点
public void add(Corp corp){
corp.setParent(this); //添加节点的时候也为下层节点添加父节点
this.list.add(corp);
}
//查看自己有哪些下层节点
public List<Corp> getList(){
return this.list;
}
}