组合模式有两种不同的实现方法
1.是透明模式
2,是安全模式 之前的例子是安全模式
其实透明模式就是把用来组合使用的方法放到了抽象类中,比如add(),remove()以及getChildren等方法(一般来说getChildren方法返回的是Iterable的实现类),不管叶子节点还是树枝节点都有相同的结构,通过判断getChildren的返回值确定是叶子节点还是树枝节点,如果处理不当,这里会发生问题,但是安全模式就不一样了,树枝节点和树叶节点的是彻底分开的,树枝节点单独拥有用来组合的方法,相比透明模式,安全模式就显得安全许多
抽象构件
public abstract class Component {
private String name = "";
private String position = "";
private int salary = 0;
//通过构造函数传递信息
public Component(String _name, String _position, int _salary){
this.name = _name;
this.position = _position;
this.salary = _salary;
}
public String getInfo() {
String info = "";
info = "名称:" + this.name;
info = info + "\t职位:" + this.position;
info = info + "\t薪水:" + this.salary;
return info;
}
public abstract void add(Component component);
public abstract void remove(Component component);
public abstract ArrayList<Component> getChildren();
}
叶子节点
public class Leaf extends Component {
public Leaf(String _name, String _position, int _salary) {
super(_name, _position, _salary);
}
@Deprecated
public void add(Component component) {
//空实现 直接抛出一个“不支持请求”异常
throw new UnsupportedOperationException();
}
@Deprecated
public void remove(Component component) {
//空实现 直接抛出一个“不支持请求”异常
throw new UnsupportedOperationException();
}
@Deprecated
public ArrayList<Component> getChildren() {
//空实现 直接抛出一个“不支持请求”异常
throw new UnsupportedOperationException();
}
}
因为叶子节点没有相关操作,所以加上@Deprecated注解,编译期就会告诉调用者,可以调用这个方法,“该方法已经失效”,在运行期间也会抛出UnsupportedOperationException异常
树枝节点
public class Branch extends Component {
//保存树枝节点下的子树枝节点和树叶节点,也就是高级下属和基础下属
private ArrayList subordinateList = new ArrayList();
public Branch(String _name, String _position, int _salary) {
super(_name, _position, _salary);
}
@Override
public void add(Component component) {
this.subordinateList.add(component);
}
@Override
public void remove(Component component) {
this.subordinateList.remove(component);
}
@Override
public ArrayList<Component> getChildren() {
return this.subordinateList;
}
}
树枝节点
public class Branch extends Component {
//保存树枝节点下的子树枝节点和树叶节点,也就是高级下属和基础下属
private ArrayList subordinateList = new ArrayList();
public Branch(String _name, String _position, int _salary) {
super(_name, _position, _salary);
}
@Override
public void add(Component component) {
this.subordinateList.add(component);
}
@Override
public void remove(Component component) {
this.subordinateList.remove(component);
}
@Override
public ArrayList<Component> getChildren() {
return this.subordinateList;
}
}
遍历
public class Main {
public static void main(String[] args) {
//组装一个组织结构
Branch ceo = compositeCorpTree();
//打印ceo信息
System.out.println(ceo.getInfo());
//打印所有员工信息
System.out.println(getTree(ceo));
}
private static Branch compositeCorpTree(){
//先产生一个CEO
Branch ceo = new Branch("刘备","总经理",10000);
//产生树枝节点 高级下属三个部门经理
Branch developDep = new Branch("诸葛亮","研发部经理",5000);
Branch salesDep = new Branch("关羽","销售部经理",5000);
Branch financeDep = new Branch("张飞","财务部经理",5000);
//生成一个子树枝节点 组长
Branch developGroup = new Branch("马谡","研发部组长",3000);
//生成员工
Leaf k = new Leaf("k","CEO秘书",1000);
Leaf a = new Leaf("a","员工A",1000);
Leaf b = new Leaf("b","员工B",1000);
//总经理定义
ceo.add(developDep);
ceo.add(salesDep);
ceo.add(financeDep);
ceo.add(k);
//部门经理定义
developDep.add(developGroup);
salesDep.add(b);
//组长定义
developGroup.add(a);
return ceo;
}
//打印
private static String getTree(Component root){
ArrayList<Component> subordinateList = root.getChildren();
String info = "";
for (Component s : subordinateList){
if (s instanceof Leaf){
info = info +s.getInfo()+"\n";
}else {
info = info+ s.getInfo()+" \n" + getTree(s);
}
}
return info;
}
}
仅仅在遍历的时候不用进行强制类型转换了,其他组装没有任何变化,透明模式的好处是遵循了依赖倒置原则,方便拓展