• 2007-11-07

    程序设计语言的表达——一个例子

    Tag:向上走

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://www.blogbus.com/dreamhead-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,这篇算是它的一个例子吧!

    分享到:

    历史上的今天:

    引用地址:

    评论

  • 就上述java的代码例子而言,可以考虑用动态代理模式来解决,这也许是比较优雅的一种方式。
    不过,看得出作者这篇blog意在通过对比不同语言在同一个问题的表达方式的异同,以说明Ruby在语言表达上所具有的优势,呵呵!
  • 如果這種現象很多的話, 我想可以考慮用AOP來做這個處理
    回复huhuVinter说:
    我不确定有多少项目可以用到AOP。
    2007-11-11 22:34:08
  • http://docs.google.com/Doc?id=dczg8vtk_759fbfz8q
  • def check_targets_before(func):
    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