WEB开发网
开发学院软件开发Java 演化架构与紧急设计: 语言、表达性与设计:第 2 部... 阅读

演化架构与紧急设计: 语言、表达性与设计:第 2 部分

 2009-11-05 00:00:00 来源:WEB开发网   
核心提示: 清单 14. 测试接口切换deftest_pegs_switchinghole=RoundHole.new(4.0)4.upto(7)do|i|peg=SquarePeg.new(i)peg.with_interface(:holes)doif(i<6)asserthole.peg_fit


清单 14. 测试接口切换
def test_pegs_switching 
 hole = RoundHole.new( 4.0 ) 
 4.upto(7) do |i| 
  peg = SquarePeg.new(i) 
  peg.with_interface(:holes) do 
   if (i < 6) 
    assert hole.peg_fits?(peg) 
   else 
    assert ! hole.peg_fits?(peg) 
   end 
  end 
 end 
end 

在 with_interface 代码块的作用域中,可以调用使用该接口名定义的 radius 方法。清单 15 中的代码实现了此功能,其结构不但紧凑而且相当简洁。其作用是提供上下文参考;其大多数内容都是比较高级的 Ruby 元编程,因此本文并不会详细讨论它。


清单 15. 接口切换魔力
class Class 
 def def_interface(interface, *syms) 
  @__interface__ = {} 
  a = (@__interface__[interface] = []) 
  syms.each do |s| 
   a << s unless a.include? s 
   alias_method "__#{s}_#{interface}__".intern, s 
   remove_method s 
  end 
 end 
end 
 
 
module InterfaceSwitching 
 def set_interface(interface) 
  unless self.class.instance_eval{ @__interface__[interface] } 
   raise "Interface for #{self.inspect} not understood." 
  end 
  i_hash = self.class.instance_eval "@__interface__[interface]" 
  i_hash.each do |meth| 
   class << self; self end.class_eval <<-EOF 
    def #{meth}(*args, &block) 
        send(:__#{meth}_#{interface}__, *args, &block) 
    end 
   EOF 
  end 
  @__interface__ = interface 
 end 
 
 def with_interface(interface) 
  oldinterface = @__interface__ 
  set_interface(interface) 
  begin 
   yield self 
  ensure 
   set_interface(oldinterface) 
  end 
 end 
end 

清单 15 中比较有趣的地方是开放类 Class 定义的结束部分:为指定方法赋予了另一个名称(基于接口),然后通过代码将它从代码中删除。更加有趣的代码出现在 InterfaceSwitching 中:set_interface 方法为在 with_interface 方法中创建的代码块的作用域重新定义了原始(重命名的)方法。最后的 ensure 代码块是 Ruby 版本的 finally 代码块。

此练习的目的并不是深入探讨 Ruby 中的充满魔力的元编程,而是演示表达性极佳的语言能实现哪些功能。解释语言始终比编译语言具有更大的优势,因为它们可以执行编译语言无法执行的代码。事实上,Groovy 引入了一种编译时元编程机制,即 AST Transformations。

结束语

本文的所有这些论述证明了什么呢?在各种语言中,表达性就相当于其能力。本文中介绍的许多技巧都是 Java 语言所不支持的,甚至使用 Javassist 等工具提供的字节码生成功能也无法从技术上实现它们。但是,使用这些机制来解决问题可以说是极其麻烦的。此态度也影响了惯用模式。即便您可以看到特定于应用程序的模式,但如果获得收益的方法过于困难,则会让您的项目背上数不清的技术债务。表达性对计算机语言的重要性是不言而喻的!

上一页  5 6 7 8 9 10 

Tags:演化 架构 紧急

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