-
2007-11-07
程序设计语言的表达——一个例子
版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://dreamhead.blogbus.com/logs/10692436.html
写程序的时候,经常遇到这样的代码。处理之前,先检验一下一些参数,之后再进行处理。下面是一段这样的Java程序。
public class Service {
public void approve() {
Target[] targets = getTargets();
if (targets.length == 0) {
reportNoTarget();
return;
}
actualApprove(targets);
}
public void reject() {
Target[] targets = getTargets();
if (targets.length == 0) {
reportNoTarget();
return;
}
actualReject(targets);
}
...
}
这段代码不够漂亮,这是显然的,因为其中存在重复代码,参数检验的部分是完全相同的,这两个函数的真正的差别只是在检验后的处理。但是在
Java中,想简单的解决这种重复并不是一件容易的事情。我脑子里想到的方案包括用异常和接口,不过,这两种方法都不够优雅,其主要原因还是因
为Java的函数并不容易操作。如果你有什么好的解决方案,不妨告诉我。
如果我们用的是C#,这段代码可以这样来写。
public class Service
{
private delegate void ActualOperationDelegate(Target[] targets);
public void Approve()
{
OperateOnTarget(ActualApprove);
}
public virtual void RejectTrades()
{
OperateOnTarget(ActualReject);
}
private void OperateOnTarget(ActualOperationDelegate operation)
{
Target[] targets = GetTargets();
if (targets.length == 0) {
ReportNoTarget();
return;
}
operation(trades);
}
...
}
这段C#代码用delegate轻松的解决了重复代码的问题。
如果用Ruby,我们可以让程序更为优雅。
class Service
def approve
operation_on_target { |targets| actual_approve targets }
end
def reject
operation_on_target { |targets| actual_reject targets }
end
def operation_on_target
targets = get_target
if (targets.length == 0)
report_no_target
end
yield targets
end
...
end之前写过一篇关于程序设计语言表达的blog,这篇算是它的一个例子吧!
引用地址:
程序设计语言的表达——内部DSL
Blog:梦想风暴2008-03-26 00:35:37








评论
不过,看得出作者这篇blog意在通过对比不同语言在同一个问题的表达方式的异同,以说明Ruby在语言表达上所具有的优势,呵呵!
def new_func(targets):
if not targets:
report_no_targets()
return false
return func(targets)
new_func.__name__ = func.__name__
return new_func
@check_targets_before
def approve(targets):
# do some thing
@check_targets_before
def reject(targets):
# do some thing