快速业务通道

演化架构与紧急设计: 语言、表达性与设计 - 第2部分 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-15
peg)    else     assert ! hole.peg_fits?(peg)    end   end end

在本例中,我可以直接对 SquarePeg 类调用 radius 方法,因为它已经包含一个 radius 方法。通过 开放类添加一个方法可以完全避免对单独适配器类的需要,无论是通过手写还是自动生成。但是,此代码 存在一个潜在的问题:如果 SquarePeg 类已经包含一个与圆孔没有任何关系的 radius 方法,那又该怎 么办呢?使用开放类会重写这个原始类,从而导致意外行为。

这正是表达性语言的强大之处。考虑如清单 13 所示的 Ruby 代码:

清单 13. 接口切换

class SquarePeg   include InterfaceSwitching   def radius    @width   end   def_interface :square, :radius   def radius    Math.sqrt(((@width/2) ** 2) * 2)   end   def_interface :holes, :radius   def initialize(width)    set_interface :square    @width = width   end end

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

时间:2011-08-18 IBM Neal Ford

此代码基本上无法使用 Java 语言或 Groovy 实现。注意,我使用 radius 这个名称定义了两个方法 。在 Groovy 中,编译器不会编译此代码。但是,Ruby(以及 JRuby)是一种解释语言,它允许您在解释 过程中 执行代码。某些 Ruby 爱好者将 Ruby 中的结构(constructs)称为 “一等市民”,表示该语言 的所有部分都是随时可用的。此处的魔力在于(类似于关键字)def_interface 方法调用。这是对在解释 时执行的 Class 类定义的一个元编程方法。这代码允许您为某个方法定义一个特定的接口,并设定该方 法只能存在于特定的作用域内。此作用域是由 with_interface 方法调用定义的,如清单 14 所示:

清单 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)    be

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号