在我们的项目中就遇到了问题,当时感觉如果应用了装饰模式的话,那么就不会这么麻烦了。
装饰模式的基本实现示意图如下:
原始接口:定义一个接口方法schoolReport;
默认目标实现类:对于原始接口的默认实现方式。也就是有待扩展的类FouthGradeSchoolReport。
装饰实现类:同样实现了原始接口,既可以是一个抽象类,也可以是一个具体实现类。其内部封装了一个原始接口的对象Decorator。
具体实现类:继承装饰类,可以选择性的覆盖实现装饰类中的方法,也可以添加自己的方法HighScoreDecorator。
那么会有人问,这和直接采用继承方式有什么不同呢?
我一开始也会有这样的疑问,后来仔细推敲发现,第一:适合对默认目标实现中的多个接口进行排列组合调度。第二:适合对默认目标实现进行选择性拓展。第三:默认目标实现未知或者不易拓展的情况。
也就是说,继承是单继承,而接口可以多继承。再就是极强的拓展性,如果你采用传统的继承,如果父类增加了一个方法,那么如果用很多子类,你要每一个子类都去实现这个方法,我靠那就真的疯了。相比之下,你的原始接口添加方法,只需要装饰类添加一个就可以,具体实现类可以不去添加,是不是轻巧了许多,哈哈。
下面是struts2中的装饰模式的使用:
public class OgnlValueStack implements Serializable, ValueStack, ClearableValueStack, MemberAccessValueStack {
//使用装饰模式,将根对象(栈结构)封装在ValueStack内部,从外界看来,所有的操作就像针对单一对象的操作,实际上在内部,实现了对栈的遍历
CompoundRoot root;
//构造函数,这里将制定ognl计算时所需要的参数
protected OgnlValueStack(XWorkConverter xworkConverter, CompoundRootAccessor accessor, TextProvider prov, boolean allowStaticAccess) {
//调用setRoot方法完成初始化
setRoot(xworkConverter, accessor, new CompoundRoot(), allowStaticAccess);
push(prov);
}
protected void setRoot(XWorkConverter xworkConverter, CompoundRootAccessor accessor, CompoundRoot compoundRoot,
boolean allowStaticMethodAccess) {
this.root = compoundRoot;
//设定ognl所需要的MemeberAcccess实现类
this.securityMemberAccess = new SecurityMemberAccess(allowStaticMethodAccess);
//创建ognl的上下文
this.context = Ognl.createDefaultContext(this.root, accessor, new OgnlTypeConverterWrapper(xworkConverter), securityMemberAccess);
context.put(VALUE_STACK, this);
//设定ognl上下文所需的其他参数
Ognl.setClassResolver(context, accessor);
((OgnlContext) context).setTraceEvaluations(false);
((OgnlContext) context).setKeepLastEvaluation(false);
}
CompoundRoot源码:
public class CompoundRoot extends ArrayList {
public CompoundRoot() {
}
public CompoundRoot(List list) {
super(list);
}
public CompoundRoot cutStack(int index) {
return new CompoundRoot(subList(index, size()));
}
public Object peek() {
return get(0);
}
public Object pop() {
return remove(0);
}
public void push(Object o) {
add(0, o);
}
}
可以看到继承了ArrayList,这里自己思考吧,ArrayLIst经过修改很容易成为一个栈结构实现“先进后出”。