重构按类型分派处理

在MeteorTL([url]http://www.meteortl.org[/url])中,多处遇到需要按类型分派处理,如:BinaryOperatorHandler,UnaryOperatorHandler,PropertyHandler,OutputFormatter,StringSequence等,
以BinaryOperatorHandler为例:
当引擎遇到二元操作符会回调BinaryOperatorHandler进行求值,接口如下:

public interface BinaryOperatorHandler extends OperatorHandler {

// 传入操作数,返回求值结果
public Object doEvaluate(Object leftOperand, Object rightOperand)
throws ExpressionException;

}


但有的操作符是重载的,
如:加号(+),在操作数为“数字”和“字符串”时要进行不同的操作,

1.最直接的实现方法是使用instanceof逐个判断,但其可扩展性极差,实现如下:

public class AddBinaryOperatorHandler implements BinaryOperatorHandler {

public Object doEvaluate(Object leftOperand, Object rightOperand)
throws ExpressionException {
if (leftOperand instanceof Integer && leftOperand instanceof Integer)
return new Integer(((Integer)leftOperand).intValue()
+ ((Integer)rightOperand).intValue());
/* 如果要添加一个日期加法,就需要修改代码加入else if
else if (leftOperand instanceof Date && leftOperand instanceof DateNumber)
return new Date(((Date)leftOperand).getTime()
+ ((DateNumber)rightOperand).getTime());*/
else
return String.valueOf(leftOperand) + String.valueOf(rightOperand);
}

}


2.职责链模式,每个Handler持有下一个Handler的引用,实现如下:

public abstract class BinaryOperatorHandlerChain implements BinaryOperatorHandler {

private BinaryOperatorHandler nextHandler;

protected BinaryOperatorHandler getNextHandler() {
return nextHandler;
}

public void setNextHandler(BinaryOperatorHandler nextHandler) {
this.nextHandler = nextHandler;
}

}

public class IntegerAddBinaryOperatorHandler extends BinaryOperatorHandlerChain {

public Object doEvaluate(Object leftOperand, Object rightOperand)
throws ExpressionException {
if (leftOperand instanceof Integer && leftOperand instanceof Integer)
return new Integer(((Integer)leftOperand).intValue()
+ ((Integer)rightOperand).intValue());
return getNextHandler().doEvaluate(leftOperand, rightOperand);
}

}

public class StringAddBinaryOperatorHandler extends BinaryOperatorHandlerChain {

// @overwrite
public void setNextHandler(BinaryOperatorHandler nextHandler) {
throw new ConfigurationException("字符串相加为终结处理,不能有下一Handler!");
}

public Object doEvaluate(Object leftOperand, Object rightOperand)
throws ExpressionException {
return String.valueOf(leftOperand) + String.valueOf(rightOperand);
}

}


3. 用一个包装类,注册相应类型的处理类,实现如下:

public class BinaryOperatorHandlerDispatcher implements BinaryOperatorHandler {

private final Map matchHandlers; //类型为<BinaryOperandMatcher, BinaryOperatorHandler>

private final BinaryOperatorHandler defaultHandler;

public BinaryOperatorHandlerDispatcher(Map matchHandlers, BinaryOperatorHandler defaultHandler) {
this.matchHandlers = matchHandlers;
this.defaultHandler = defaultHandler;
}

public Object doEvaluate(Object leftOperand, Object rightOperand)
throws ExpressionException {
// 在集合中匹配相应类型的处理器
for (Iterator iterator = matchHandlers.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry = (Map.Entry)iterator.next();
if (((BinaryOperandMatcher)entry.getKey()).isMatch(leftOperand, rightOperand))
return ((BinaryOperatorHandler)entry.getValue()).doEvaluate(leftOperand, rightOperand);
}
// 未找到相应类型的处理器则使用默认处理器
if (defaultHandler != null)
return defaultHandler.doEvaluate(leftOperand, rightOperand);
//否则抛出异常
throw new UnhandleException("没有找到相应处理类!");
}

}

public class BinaryOperandMatcher {

private final Class leftOperandClass;

private final Class rightOperandClass;

public BinaryOperandMatcher(Class leftOperandClass, Class rightOperandClass) {
this.leftOperandClass = leftOperandClass;
this.rightOperandClass = rightOperandClass;
}

// 匹配操作数类型
public boolean isMatch(Object leftOperand, Object rightOperand) {
return isMatchClass(leftOperand, leftOperandClass) && isMatchClass(rightOperand, rightOperandClass);
}

private boolean isMatchClass(Object operand, Class operandClass) {
if (operandClass == null || operand == null)
return operandClass == null && operand == null;
return operandClass.isAssignableFrom(operand.getClass());
}

}

public class IntegerAddBinaryOperatorHandler implements BinaryOperatorHandler {

public Object doEvaluate(Object leftOperand, Object rightOperand)
throws ExpressionException {
assert(leftOperand instanceof Integer && leftOperand instanceof Integer);
return new Integer(((Integer)leftOperand).intValue() + ((Integer)rightOperand).intValue());
}

}

public class StringAddBinaryOperatorHandler implements BinaryOperatorHandler {

public Object doEvaluate(Object leftOperand, Object rightOperand)
throws ExpressionException {
return String.valueOf(leftOperand)
+ String.valueOf(rightOperand);
}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值