JAVA设计模式学习10——组合模式
这节开始学习结构模式,结构模式包括:组合模式、门面模式、适配器模式、代理模式、装饰模式、桥模式、享元模式。从组合模式开始学习。
组合模式(Composite)就是把部分和整体的关系用树形的结构来表示,从而使客户端能够把部分对象和组合起来的对象采用同样的方式来看待。
树图结构一般包含一个根节点,若干个树枝和叶子节点。如下图:
可以用一个类图描述树结构的静态结构,把根节点当做树枝节点来描述,同时和叶子节点具有共同的父类:树结构的类图,其实就是组合模式的简略类图,最上面为抽象节点,左下方为叶子节点,右下方为树枝节点,它含有其他的节点。
通过以上结构图可以看出,组合模式有以下角色:1、抽象构建角色(component):作为抽象角色,给组合对象的统一接口。
2、树叶构建角色(leaf):代表组合对象中的树叶对象。
3、树枝构建角色(composite):参加组合的所有子对象的对象,并给出树枝构构建对象的行为。
组合模式在现实中使用很常见,比如文件系统中目录和文件的组成,算式运算,android里面的view和viewgroup等控件,淘宝产品分类信息的展示等都是组合模式的例子。还有个故事:从前山里有座庙,庙里有个老和尚,老和尚对象小和尚讲故事说,从前山里有个庙......退出循环的条件是听厌烦了,或者讲的人讲累了。
这个模式的举例最多的是公司员工的例子。我们这里也以故事雇员为例子来描述:
?
?
package composite;/** * *作者:alaric *时间:2013-7-20下午5:11:41 *描述:员工和领导的统一接口 */public interface Worker {public void doSomething();}
?
package composite;/** * *作者:alaric *时间:2013-7-20下午5:59:11 *描述:普通员工类 */public class Employe implements Worker {private String name;public Employe(String name) {super();this.name = name;}@Overridepublic void doSomething() {System.out.println(toString());}@Overridepublic String toString() {// TODO Auto-generated method stubreturn "我叫"+getName()+",就一普通员工!";}public String getName() {return name;}public void setName(String name) {this.name = name;}}
?
package composite;import java.util.Iterator;import java.util.List;import java.util.concurrent.CopyOnWriteArrayList;/** * *作者:alaric *时间:2013-7-20下午5:14:50 *描述:领导类 */public class Leader implements Worker {private List<Worker> workers = new CopyOnWriteArrayList<Worker>(); private String name;public Leader(String name) {super();this.name = name;}public void add(Worker worker){workers.add(worker);}public void remove(Worker worker){workers.remove(worker);}public Worker getChild(int i){return workers.get(i);}@Overridepublic void doSomething() {System.out.println(toString());Iterator<Worker> it = workers.iterator();while(it.hasNext()){it.next().doSomething();}}@Overridepublic String toString() {// TODO Auto-generated method stubreturn "我叫"+getName()+", 我是一个领导,有 "+workers.size()+"下属。";}public String getName() {return name;}public void setName(String name) {this.name = name;}}
?
package composite;/** * *作者:alaric *时间:2013-7-20下午5:49:37 *描述:测试类 */public class Client {/** *作者:alaric *时间:2013-7-20下午5:49:32 *描述: */public static void main(String[] args) {// TODO Auto-generated method stubLeader leader1 = new Leader("张三");Leader leader2 = new Leader("李四");Employe employe1 = new Employe("王五");Employe employe2 = new Employe("赵六");Employe employe3 = new Employe("陈七");Employe employe4 = new Employe("徐八");leader1.add(leader2);leader1.add(employe1);leader1.add(employe2);leader2.add(employe3);leader2.add(employe4);leader1.doSomething();}
?运行结果如下:
我叫张三, 我是一个领导,有 3个直接下属。
我叫李四, 我是一个领导,有 2个直接下属。
我叫陈七,就一普通员工!
我叫徐八,就一普通员工!
我叫王五,就一普通员工!
我叫赵六,就一普通员工!
上面员工关系的的树形结构如下:
上面例子给出的组合模式抽象角色里,并没有管理子节点的方法,而是在树枝构建角色,这种模式使得叶子构建角色和树枝构建角色有区分,客户端要分别对待树叶构建角色和树枝构建角色,好处是客户端对叶子节点不会调用管理的方法,当调用时,在编译时就会报错,所以也称安全模式。相对安全模式,还有一种透明模式,就是在抽象角色里面添加管理方法,如下图:
?