快速业务通道

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

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-15
许您重新打开已有类并向它们添加新的方法,而不需 要子类化过程。当您需要更改基础架构某部分(例如,集合 API)所使用的某个类的行为,而该行为又需 要某个特定的类时,这种方式极为方便。您可以修改已有类,将它作为参数传递,并利用 API,而不需要 基础 API 声明一个抽象类或接口。开放类还允许您执行 “就地” 修改,而不需要子类化过程。

但是,修改整个类定义听起来有点令人担心:您可能不希望对整个类执行全面修改。幸运的是, Groovy 和 Ruby 都允许您向单个类实例 添加新的方法。换句话说,您可以向某个 Logger 实例添加一个 新方法,而不会影响它的所有其他实例。清单 3 显示如何使用 ExpandoMetaClass 在 Groovy 中重写某 个 Logger 实例的 log() 方法:

清单 3. 重写某个 Logger 实例的 log() 方法

def logger = new Logger() logger.metaClass.log = { String m ->   println m.toUpperCase() } logger.log "this log message brought to you in upper case"

理解了此机制的工作原理之后,阅读此代码要比阅读使用额外类的相应代码更加轻松。所有相关的修 饰代码都出现在一个位置,而不是分散于若干个文件中(因为在 Java 语言中,每个公有类都必须位于它 自己的文件中)。

Ruby 也提供了相同的功能,即所谓的 singleton method(这是一个令人疑惑的名称,因为 singleton 代表着负载过重)或者 eigenclass。在 JRuby 中实现的代码如清单 4 所示:

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

时间:2011-08-18 IBM Neal Ford

清单 4. 使用 Ruby 的 eigenclass 执行就位修饰

class Logger   def log(msg)    puts msg   end end l = Logger.new def l.log m   puts m.upcase end l.log "this log message brought to you in upper case"

Ruby 版本并未使用额外的工具,比如说 ExpandoMeta Class。在 Ruby 中,您可以为某个特定的实例 定义一个内联方法,其方法是将变量名称放在方法声明的最前面。Ruby 具备极佳的语法灵活性,因此对 可以在何时及何处定义方法并没有太多规则限制。

这工具还适用于内置 Java 类。举例来说,应该使用 first() 和 last() 方法来定义 ArrayList 类 ,不过并未采用这种方式。但是,在 Groovy 中添加这些方法是相当简单的,如清单 5 所示:

清单 5. 在 Groovy 中为 ArrayList 添加 first() 和 last() 方法

ArrayList.metaClass.getFirst {   delegate.size > 0 ? get(0) : null } ArrayList.metaClass.getLast {   delegate.size > 0 ? get(delegate.size - 1) : null } ArrayList l = new ArrayList() l << 1 << 2 << 3 println l.first println l.last ArrayList emptyList = new ArrayList() println emptyList.first println emptyList.last

使用 ExpandoMetaClass,您可以为类定义一些新的属性(使用熟悉的 Java get/set 命名模式)。为 类定义了新的属性之后,可以将它们像普通属性一样调用。

您可以像在 JRuby 中一样使用已有的 JDK 类实现相同的目的,如清单 6 所示:

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

时间:2011-08-18 IBM Neal Ford

清单 6. 使用 JRuby 为 ArrayList 添加方法

require ''java'' include_class ''java.util.ArrayList'' class ArrayList   def first    size != 0 ? get(0) : nil   end   def last    size != 0 ? get(size - 1) : nil   end end list = ArrayList.new l << 1 << 2 << 3

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站: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号