组合模式(java实现)

来源:互联网 发布:工业组态软件 编辑:程序博客网 时间:2024/06/05 18:41

组合模式

如果把北京总公司比作一个大树的话,它的下属分公司就是这棵树的分枝,至于各办事处是更小的分支,而它们的相关职能部门由于没有分枝了,可以理解为树叶.尽管天下没有相同的树叶,但是同一棵树上长出来的树叶样子也不会相差到哪去.也就是说,若使总部的财务管理功能复用于子公司,最好的办法是,处理总公司的财务管理功能和处理子公司的财务管理功能的方法是一样的.

组合模式:

将对象组成树形结构,以表示部分-整体的层次结构.组合模式使得用户对单个对象和组合对象的使用具有一致性.

public abstract class Component {

protected String name;

public Component(String name) {

this.name =name;

}

public abstract void add(Component c);

public abstract void remove(Component c);

public abstract void display(int depth);

}

//叶节点下没有子节点

public class Leaf extends Component {

public Leaf(String name) {

super(name);

}

@Override

public void add(Component c) {

//由于叶子没有再增加分枝和树叶,所以add和remove方法对实现它没有意义

//但是这样做可以消除叶节点和枝节点对象在抽象层次的区别,它们具有完全一致的接口

System.out.println("cannot add a leaf");

}

@Override

public void remove(Component c) {

System.out.println("cannot remove from a leaf");

}

@Override

public void display(int depth) {

//显示其级别和名称

for(int i=0;i<depth;i++) {

System.out.print("-");

}

System.out.println(name);

}

}

public class Composite extends Component {

private List<Component>children=new ArrayList<Component>();

public Composite(String name) {

super(name);

}

@Override

public void add(Component c) {

children.add(c);

}

@Override

public void remove(Component c) {

children.remove(c);

}

@Override

public void display(int depth) {

for(int i=0;i<depth;i++) {

System.out.print("-");

}

System.out.println(name);

depth+=2;

for (Component component :children) {

//System.out.println(component);

component.display(depth);

}

}

}

public class Demo {

public static void main(String[]args) {

//生成树根root,根上长出两片叶子LeafA,和LeafB

Composite root=new Composite("root");

root.add(new Leaf("Leaf A"));

root.add(new Leaf("Leaf B"));

//根上长出分支CompositeX,分支上有两片叶子LeafXA和LeafXB

Composite comp=new Composite("CompositeX");

comp.add(new Leaf("Leaf XA"));

comp.add(new Leaf("Leaf XB"));

root.add(comp);

//在CompositeX上再长出两片叶子LeafXYA和LeafXYB

Composite comp2=new Composite("CompositeXY");

comp2.add(new Leaf("Leaf XYA"));

comp2.add(new Leaf("Leaf XYB"));

comp.add(comp2);

//展示大树的形态

root.display(1);

}

}

问题描述:为什么Leaf类中也有addremove方法,树叶不是不可以再长分支吗?这种方式是透明方式,Component中声明所有用来管理子对象的方法,这样实现Component接口的所有子类都具备了addremove.这样做的好处是叶节点和枝节点对于外界没有区别,它们具备完全一致的行为接口.但是问题来了,由于Leaf类本身没有addremove方法,所以实现它是没有意义的.使用安全方式可以避免做这样的无用功,就是在接口Component接口中不去声明addremove方法,那么子类的Leaf也不需要去实现它,而是在Composite声明所有用来管理子类对象的方法,但是由于不够透明,所以树叶和树枝类将不具有相同的接口,客户端调用需要进行相应的判断,带来了不便.两者各有好处,视情况而定

何时使用组合模式?

需求中是体现部分和整体层次的结构时,你希望用户可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就可以考虑使用组合模式了.

组合模式的好处?

基本对象可以被组合成更复杂的组合对象,而这个组合对象又可以被组合.用户是不用关心到底是处理一个叶节点还是处理一个组合组件,也就用不着为定义组合而写一些判断的语句.说白了,组合模式让客户可以一致地使用组合结构和单个对象.

原创粉丝点击