WEB开发网
开发学院软件开发Java 演化架构和紧急设计: 使用 Groovy 构建 DSL 阅读

演化架构和紧急设计: 使用 Groovy 构建 DSL

 2010-10-09 08:12:32 来源:WEB开发网   
核心提示: queue.dequeue().shouldBe(val)但是 Queue 类的检查显示它没有一个 shouldBe()方法,那么它是从哪里来的呢? 如果您查看 it() 方法的定义,演化架构和紧急设计: 使用 Groovy 构建 DSL(8),您将可以看到 categories 用在何处来扩展

queue.dequeue().shouldBe(val)

但是 Queue 类的检查显示它没有一个 shouldBe()方法。那么它是从哪里来的呢?

如果您查看 it() 方法的定义,您将可以看到 categories 用在何处来扩展已有类。清单 9 显示 it() 方法的声明:

清单 9. it() 方法的声明

def it(spec, closure) { 
  stepStack.startStep(listener, BehaviorStepType.IT, spec) 
  closure.delegate = new EnsuringDelegate() 
  try { 
    if (beforeIt != null) { 
      beforeIt() 
    } 
    listener.gotResult(new Result(Result.SUCCEEDED)) 
  use(BehaviorCategory) { 
      closure() 
    } 
    if (afterIt != null) { 
      afterIt() 
    } 
  } catch (Throwable ex) { 
    listener.gotResult(new Result(ex)) 
  } 
  stepStack.stopStep(listener) 
} 

大约一半的方法,作为参数传递的封闭块将在 BehaviorCategory 类中执行,清单 10 显示了其中的一部分:

清单 10. BehaviorCategory 类的一部分

static void shouldBe(Object self, value, String msg) { 
  isEqual(self, value, msg) 
} 
 
private static void isEqual(self, value, String msg) { 
  if (self.getClass() == NullObject.class) { 
    if (value != null) { 
      throwValidationException( 
        "expected ${value.toString()} but target object is null", msg) 
    } 
  } else if (value.getClass() == String.class) { 
    if (!value.toString().equals(self.toString())) { 
      throwValidationException( 
        "expected ${value.toString()} but was ${self.toString()}", msg) 
    } 
  } else { 
    if (value != self) { 
      throwValidationException("expected ${value} but was ${self}", msg) 
    } 
  } 
} 

BehaviorCategory 是一个 category ,其方法扩增了 Object,阐述了开放类令人难以置信的力量。向 Object 添加一个新方法,这使得向每个类(包括 Queue)添加一个 shouldBe() 方法变得十分容易。您不能使用核心 Java 代码进行这一操作,这样做太麻烦了,甚至没法入手。categories 的使用加强了我之前的建议:它将对 Object 的修改范围限制为 easyb DSL 中 use 子句。

结束语

我想让我捕获的惯用模式从其余的代码中脱颖而出,DSL 提供一个令人信服的机制来实现这一目标。使用支持它们的语言编写 DSL 非常容易,不像使用 Java 语言那样。如果您组织的外部力量妨碍您利用非 Java 语言的优势,不要放弃。像 Spring 框架这类语言越来越多地支持其他语言,比如 Groovy 或 Clojure。您可以使用这些语言来创建部件并让 Spring 将其注入到您应用程序的合适位置。许多组织在使用其他语言方面太过保守,但是通过 Spring 这类框架很容易增加线路。

下一期中,我将使用几个 JRuby 实例集中精力介绍使用 DSL 作为一种方法捕获领域惯用模式,阐述可以将语言的表现力呈现得多深入 。

上一页  3 4 5 6 7 8 

Tags:演化 架构 紧急

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接