【问题标题】:Groovy: automatically extend all setters for propertiesGroovy:自动扩展属性的所有设置器
【发布时间】:2015-10-15 12:59:26
【问题描述】:

如果我有这样一个 groovy 类:

class WebSession{
    String firstName
    String lastName
    String email
}

我希望能够使用自动设置器来设置值。例如:

WebSessionuser = new WebSession()
webSession.firstName = 'John'

但是让它调用的 setter 做一些额外的事情,比如记录一些东西或将对象持久化到缓存。

如何在不必手动定义所有设置器的情况下做到这一点?到目前为止,我有这样的东西,但我不能让它工作:

    webSession.properties.each{ key, value ->
        if ( key != 'class' ) {
            String methodName = "set${key.capitalize()}";
            WebSession.metaClass[key]."${methodName}" = { -> delegate
                System.out.println("Setting key: ${key}");
                webSession[key] = delegate;
            }
        }

    }

另外,我不知道循环遍历属性名称减去“类”是否很麻烦,并且有更好的方法来获取声明的字段。

【问题讨论】:

  • 通常你应该避免像这样的 getter/setter 的副作用。
  • 是的,我知道你的意思,因为它在欺骗自己在做什么,特别是如果你使用像 webSesssion.firstName = 'John' 这样的简写......你不想欺骗开发者谁认为它只是设置一个字段。但是在这种情况下,它是一个特殊的类,我们知道它总是会被持久化到会话和/或缓存中,我们希望它自动发生,而不必编写大量的管道代码来在每个 setter 上做同样的事情。

标签: groovy


【解决方案1】:

您可以通过实现void setProperty(String, Object)Object getProperty(String) 来拦截所有的getter 和setter。这是一个例子:

示例

def a = new WebSessionDecorator(new WebSession())

a.firstName = 'John'

println a.firstName

class WebSession {
    String firstName
    String lastName
    String email
}

class WebSessionDecorator {
    private WebSession delegate

    WebSessionDecorator(WebSession webSession) {
        this.delegate = webSession
    }

    void setProperty(String name, Object value) {
        println "LOG: Setting $name to $value"
        delegate.setProperty(name, value)        
    }

    def getProperty(String name) {
        println "LOG: Returning $name"
        delegate.getProperty(name)
    }
}

输出

输出如下:

LOG: Setting firstName to John
LOG: Returning firstName
John

说明

WebSessionDecorator 拦截所有财产访问,为您提供随心所欲的机会。然后,它将属性访问权委托给实际的WebSession

我选择使用装饰器是为了避免重复调用getProperty()setProperty(),并且只有在适用时才可以使用装饰器。例如,您可能不想在单元测试中使用它。

【讨论】:

  • 值得注意的是,使用setProperty()getProperty() 将覆盖看起来像您直接设置属性的用例(例如webSession.firstName = ...),但这不适用于生成的setter 和 getter,例如 webSession.setFirstName(),所以请注意不要期望它在这两种情况下都能正常工作。
  • 啊...这样就解释了。谢谢mnd!
  • 谢谢...这对我不起作用,因为我正在寻找 IDE (IntelliJ) 以了解 WebSession 上的属性(以查找参考等)。我的目标是更好地表示使用这些工具的位置。我最终得到了一些工作,我在 WebSession 类中定义 setProperty 方法,并且在里面它做了额外的东西 + this.@"$name" = value (以避免递归),从这里得到它:stackoverflow.com/questions/2075348/…跨度>
猜你喜欢
  • 2017-07-05
  • 1970-01-01
  • 2019-08-31
  • 2014-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多