一:组合模式例子:
附上源码:
类图参见书p241
IRoot.java
package combinePattern;
import java.util.ArrayList;
//根节点接口
public interface IRoot
{
public String getInfo();
public void add(IBranch branch);
public void add(ILeaf leaf);
public ArrayList getSubordinateInfo();
}
Root.java
package combinePattern;
import java.util.ArrayList;
//根节点实现
public class Root implements IRoot {
//下级的树枝节点和树叶节点
private ArrayList subordinateList = new ArrayList();
//根节点名称
private String name = "";
//根节点职位
private String position = "";
//根节点薪水
private int salary = 0;
public Root(String name,String positon,int salary)
{
this.name = name;
this.position = position;
this.salary = salary;
}
public void add(IBranch branch)
{
this.subordinateList.add(branch);
}
public void add(ILeaf leaf)
{
this.subordinateList.add(leaf);
}
public String getInfo()
{
String info = "";
info = "名称:"+this.name;
info += "\t职位:"+this.position;
info += "\t薪水:"+this.salary;
return info;
}
public ArrayList getSubordinateInfo()
{
return this.subordinateList;
}
}
IBranch.java
package combinePattern;
import java.util.ArrayList;
//有分支节点接口
public interface IBranch
{
public String getInfo();
public void add(IBranch branch);
public void add(ILeaf leaf);
public ArrayList getSubordinateInfo();
}
Branch.java
package combinePattern;
import java.util.ArrayList;
//分支节点实现类
public class Branch implements IBranch {
private ArrayList subordinateList = new ArrayList();
private String name = "";
private String position = "";
private int salary = 0;
public Branch(String name,String position,int salary)
{
this.name = name;
this.position = position;
this.salary = salary;
}
public void add(IBranch branch)
{
this.subordinateList.add(branch);
}
public void add(ILeaf leaf)
{
this.subordinateList.add(leaf);
}
public String getInfo()
{
String info = "";
info = "名称:"+this.name;
info += "\t职位:"+this.position;
info += "\t薪水:"+this.salary;
return info;
}
public ArrayList getSubordinateInfo()
{
return this.subordinateList;
}
}
ILeaf.java
package combinePattern;
//叶子节点的接口
public interface ILeaf
{
public String getInfo();
}
Leaf.java
package combinePattern;
public class Leaf implements ILeaf
{
private String name = "";
private String position = "";
private int salary = 0;
public Leaf(String name,String position,int salary)
{
this.name = name;
this.position = position;
this.salary = salary;
}
public String getInfo()
{
String info = "";
info = "名称:"+this.name;
info += "\t职位:"+this.position;
info += "\t薪水:"+this.salary;
return info;
}
}
Client.java
package combinePattern;
import java.util.ArrayList;
public class Client
{
public static void main(String[] args)
{
//根节点
IRoot ceo = new Root("王大麻子","总经理",100000);
//树枝节点
IBranch developDep = new Branch("刘大瘸子","研发部门经理",30000);
IBranch salesDep = new Branch("马二拐子","销售部门经理",20000);
IBranch financeDep = new Branch("赵三驼子","财务部门经理",10000);
//小组长
IBranch firstDevGroup = new Branch("杨三乜斜","开发一组组长",5000);
IBranch secondDevGroup = new Branch("吴大棒槌","开发二组组长",6000);
//叶子节点
ILeaf a = new Leaf("a","开发人员",4000);
ILeaf b = new Leaf("b","开发人员",4000);
ILeaf c = new Leaf("c","开发人员",4000);
ILeaf d = new Leaf("d","开发人员",4000);
ILeaf e = new Leaf("e","开发人员",4000);
ILeaf f = new Leaf("f","开发人员",4000);
ILeaf g = new Leaf("g","开发人员",4000);
ILeaf h = new Leaf("h","销售人员",2000);
ILeaf i = new Leaf("i","销售人员",2000);
ILeaf j = new Leaf("j","财务人员",2000);
ILeaf k = new Leaf("k","CEO秘书",8000);
ILeaf zhengLaoLiu = new Leaf("郑老六","研发部副总",20000);
//组装树
ceo.add(developDep);
ceo.add(salesDep);
ceo.add(financeDep);
ceo.add(k);
developDep.add(firstDevGroup);
developDep.add(secondDevGroup);
developDep.add(zhengLaoLiu);
firstDevGroup.add(a);
firstDevGroup.add(b);
firstDevGroup.add(c);
secondDevGroup.add(d);
secondDevGroup.add(e);
secondDevGroup.add(f);
salesDep.add(h);
salesDep.add(i);
financeDep.add(j);
//打印
System.out.println(ceo.getInfo());
//遍历
getAllSubordinateInfo(ceo.getSubordinateInfo());
}
private static void getAllSubordinateInfo(ArrayList subordinateList)
{
int length = subordinateList.size();
for(int m=0;m<length;m++)
{
Object s = subordinateList.get(m);
if(s instanceof Leaf)
{
ILeaf employee = (ILeaf)s;
System.out.println(((Leaf)s).getInfo());
}
else
{
IBranch branch = (IBranch)s;
System.out.println(branch.getInfo());
getAllSubordinateInfo(branch.getSubordinateInfo());
}
}
}
}
评价:每个接口都有getInfo()方法,所以应该抽象出来
Root类和Branch类差别不大,合并成一个类
修改后的类图参见书p247:
附上源码:
ICorp.java
package combinePattern2;
public interface ICorp
{
public String getInfo();
}
IBranch.java
package combinePattern2;
import java.util.ArrayList;
public interface IBranch extends ICorp
{
public void addSubordinate(ICorp corp);
public ArrayList<ICorp> getSubordinate();
}
Branch.java
package combinePattern2;
import java.util.ArrayList;
public class Branch implements IBranch {
private String name = "";
private String position = "";
private int salary = 0;
ArrayList<ICorp> subordinateList = new ArrayList<ICorp>();
public Branch(String name,String position,int salary)
{
this.name = name;
this.position = position;
this.salary = salary;
}
public void addSubordinate(ICorp corp)
{
this.subordinateList.add(corp);
}
public ArrayList<ICorp> getSubordinate()
{
return this.subordinateList;
}
public String getInfo()
{
String info = "";
info = "名称:"+this.name;
info += "\t职位:"+this.position;
info += "\t薪水:"+this.salary;
return info;
}
}
ILeaf.java
package combinePattern2;
public interface ILeaf extends ICorp
{
}
Leaf.java
package combinePattern2;
public class Leaf implements ILeaf
{
private String name = "";
private String position = "";
private int salary = 0;
public Leaf(String name,String position,int salary)
{
this.name = name;
this.position = position;
this.salary = salary;
}
public String getInfo()
{
String info = "";
info = "名称:"+this.name;
info += "\t职位:"+this.position;
info += "\t薪水:"+this.salary;
return info;
}
}
Client.java
package combinePattern2;
import java.util.ArrayList;
public class Client
{
public static void main(String[] args)
{
//调用组装函数:先组装一棵树
Branch ceo = compositeCorpTree();
//打印ceo节点
System.out.println(ceo.getInfo());
//调用遍历函数
System.out.println(getTreeInfo(ceo));
}
public static Branch compositeCorpTree()
{
Branch root = new Branch("王大麻子","总经理",100000);
Branch developDep = new Branch("刘大瘸子","研发部门经理",30000);
Branch salesDep = new Branch("马二拐子","销售部门经理",20000);
Branch financeDep = new Branch("赵三驼子","财务部门经理",10000);
Branch firstDevGroup = new Branch("杨三乜斜","开发一组组长",5000);
Branch secondDevGroup = new Branch("吴大棒槌","开发二组组长",6000);
Leaf a = new Leaf("a","开发人员",4000);
Leaf b = new Leaf("b","开发人员",4000);
Leaf c = new Leaf("c","开发人员",4000);
Leaf d = new Leaf("d","开发人员",4000);
Leaf e = new Leaf("e","开发人员",4000);
Leaf f = new Leaf("f","开发人员",4000);
Leaf g = new Leaf("g","开发人员",4000);
Leaf h = new Leaf("h","销售人员",2000);
Leaf i = new Leaf("i","销售人员",2000);
Leaf j = new Leaf("j","财务人员",2000);
Leaf k = new Leaf("k","CEO秘书",8000);
Leaf zhengLaoLiu = new Leaf("郑老六","研发部副总",20000);
//组装
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;
}
public static String getTreeInfo(Branch root)
{
ArrayList<ICorp> subordinateList = root.getSubordinate();
String info = "";
for(ICorp s : subordinateList)
{
//是叶子节点就直接输出信息
if(s instanceof Leaf)
{
info += s.getInfo()+"\n";
}
else
{
info += s.getInfo()+"\n"+getTreeInfo((Branch)s);
}
}
return info;
}
}
继续改进:将接口改成抽象类,把方法放到具体实现类中,场景类只和抽象类进行交互
类图参见书p251
附上改进后的源码:
Corp.java
package combinePattern3;
public abstract class Corp
{
private String name = "";
private String position = "";
private int salary = 0;
public Corp(String _name,String _position,int _salary)
{
this.name = _name;
this.position = _position;
this.salary = _salary;
}
public String getInfo()
{
String info = "";
info = "名称:"+this.name;
info += "\t职位:"+this.position;
info += "\t薪水:"+this.salary;
return info;
}
}
Leaf.java
package combinePattern3;
public class Leaf extends Corp
{
public Leaf(String name, String position, int salary) {
super(name, position, salary);
// TODO Auto-generated constructor stub
}
}
Branch.java
package combinePattern3;
import java.util.ArrayList;
public class Branch extends Corp
{
ArrayList<Corp> subordinateList = new ArrayList<Corp>();
public Branch(String name, String position, int salary) {
super(name, position, salary);
// TODO Auto-generated constructor stub
}
public void addSubordinate(Corp corp)
{
this.subordinateList.add(corp);
}
public ArrayList<Corp> getSubordinate()
{
return this.subordinateList;
}
}
二:组合模式的定义:
组合模式的几个角色:
1.Component抽象构建角色:定义参加组合对象的共有方法和属性
2.Leaf叶子构件:叶子对象,遍历的最小单位
3.Composite树枝构件:树枝对象,组合树枝节点和叶子节点形成一个树形结构
通用源码如下:
Component.java
package compositePattern;
//抽象构件
public abstract class Component
{
public void doSomething()
{
//编写业务逻辑
}
}
Composite.java
package compositePattern;
import java.util.ArrayList;
//树枝构件
public class Composite extends Component
{
private ArrayList<Component> componentArrayList = new ArrayList<Component>();
//增加一个叶子构件或树枝构件
public void add(Component component)
{
this.componentArrayList.add(component);
}
//删除一个叶子构件或树枝构件
public void remove(Component component)
{
this.componentArrayList.remove(component);
}
public ArrayList<Component> getChildren()
{
return this.componentArrayList;
}
}
Leaf.java
package compositePattern;
public class Leaf extends Component
{
/*可以覆写该方法doSomething()*/
}
Client.java
package compositePattern;
public class Client
{
public static void main(String[] args)
{
//创建一个根节点
Composite root = new Composite();
root.doSomething();
//创建一个树枝构件
Composite branch = new Composite();
//创建一个叶子节点
Leaf leaf = new Leaf();
//构件树
root.add(branch);
branch.add(leaf);
}
//递归遍历树
public static void display(Composite root)
{
for(Component c : root.getChildren())
{
if(c instanceof Leaf)//叶子节点
c.doSomething();
else //树枝节点
display((Composite)c);
}
}
}