Composite模式应用于客户端忽略单独的对象和组合对象之间的区别时,对于客户端而言,单独的对象和多个对象的组合同样处理,也就是说,当组合对象的数量减少或者增多时,客户端代码不用改变。
下面是一个简单的Composite模式,展示了两种男人追求女孩子的策略,一种是单枪匹马,另一种是靠朋友的帮忙来追求女孩子。好了,先看代码:
package net.liuyx.test;
import java.util.ArrayList;
import java.util.List;
public class CompositeTest {
/**
* @param args
* @throws CantAddException
* @throws CantRemoveException
*/
public static void main(String[] args) throws CantAddException, CantRemoveException {
ChaseGirls singleMan = new SingleMan();
singleMan.chase();
ChaseGirls multiMen = new MultiMen();
ChaseGirls singleMan1 = new SingleMan();
ChaseGirls singleMan2 = new SingleMan();
ChaseGirls singleMan3 = new SingleMan();
multiMen.add(singleMan1);
multiMen.add(singleMan2);
multiMen.add(singleMan3);
multiMen.remove(2);
multiMen.chase();
}
}
abstract class ChaseGirls{
public abstract void chase();
public void add(ChaseGirls girl)throws CantAddException{
throw new CantAddException("can't add a child node here");
}
public void remove(int location)throws CantRemoveException{
throw new CantRemoveException("can't add a child node here");
}
}
class SingleMan extends ChaseGirls{
@Override
public void chase() {
System.out.println("I am a single man to chase a girl,and I must pay a lot of effort to achieve this");
}
}
class MultiMen extends ChaseGirls{
private List<ChaseGirls> chaseGirls = new ArrayList<ChaseGirls>();
@Override
public void chase() {
System.out.println("A lot of men chase a girl sequencely, and the girls may not feel it");
}
@Override
public void add(ChaseGirls girl) throws CantAddException {
chaseGirls.add(girl);
}
@Override
public void remove(int location) throws CantRemoveException {
if(chaseGirls.get(location) != null)
chaseGirls.remove(location);
}
}
class CantAddException extends Exception{
public CantAddException(String msg){
super(msg);
}
}
class CantRemoveException extends Exception{
public CantRemoveException(String msg){
super(msg);
}
}
输出为:
值得注意的是,假如客户端对SingleMan直接调用add和remove时,会抛出异常,为了忽略这样的操作,可以在父类中添加一个public MultiMen getMultiMen()的方法,代码如下:
public MultiMen getMultiMen(){
return null;
}
对于Individual Object而言,可以直接只用父类的实现,而Composite Object,需要覆盖这个方法,如:
@Override
public MultiMen getMultiMen() {
return this;
}
最后,在客户端调用add和remove等方法时,进行判断就可:
if (singleMan.getMultiMen() != null) {
singleMan.add(singleMan3);
}
if (multiMen.getMultiMen() != null) {
multiMen.add(singleMan1);
multiMen.add(singleMan2);
multiMen.add(singleMan3);
}
这样,对于SingleMan这个Individual Object调用add方法时就不会抛出异常了。而且客户端并不需要知道SingleMan和MultiMen的区别。