Groovy中的信息隐藏(使用闭包或命名约定?) [英] Information-hiding in Groovy (using closures? naming conventions?)

查看:115
本文介绍了Groovy中的信息隐藏(使用闭包或命名约定?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是由于我未成功找到此问题的答案而进行的从2014年开始。

This follows from my unsuccessful attempt to find an answer to this question from 2014.

对我来说,目前尚不清楚Groovy中实际上是否存在使用闭包(特别是隐藏信息)的某些技术。我只能说,如果存在有关此类技术的信息,那么它就是信息隐藏的完美例证:我找不到它!

It's not clear to me whether there might in fact be some techniques in Groovy to use closures, specifically, to hide information. All I can say is that if information on such techniques is out there it is a perfect illustration, precisely, of "information-hiding": I cannot find it!

但是失败的是,我认为我现在的理解是,曾经进行过零次隐藏信息的尝试(或假装成Java,记住了反射技术)。这似乎是设计使然,也是由于Groovy的动态特性的要求。例如,在所提到的问题中提到的 @CompileStatic 似乎更多地是关于类型检查的。

But failing that I think my understanding now is that absolutely zero attempt to hide information (or pretend to, as in Java - bearing in mind reflection techniques) is ever made. This appears to be by design, but also due to the requirements of Groovy's dynamic nature. It seems, for example, that @CompileStatic, mentioned in the referenced question, is more about type-checking than anything else.

但是,例如在Python中,有一个约定(我认为仍在使用),以使本应被视为私有的字段以双下划线开头。我从未听说过有人谈论与Groovy相关的事情。

But in Python, for example, there is a convention (I assume still used) to make "fields which are meant to be considered private" begin with a double underscore. I've never heard anyone talking about this in connection with Groovy.

不是信息隐藏和封装,或者至少是鼓励规范使用亲密关系的惯例状态的物体,好东西?有任何Groovy专家愿意评论吗?

Aren't information-hiding and encapsulation, or at least conventions to encourage disciplined use of the "intimate state" of objects, good things? Any Groovy experts care to comment?

稍后

later

daggett给出了一个在某些方面很有趣的答案,但并不是我真正想到的。考虑以下内容:

daggett has given an answer which is interesting in some ways, but not really what I had in mind. Consider this:

class Main {
    static main( args ) {
        def sm = new SecurityManager()
        System.setSecurityManager( sm )
        println new Bob().doSomethingProtected()
    }
}


class Bob {
    public doSomethingPublic() {
        "public"
    }
    private doSomethingPrivate() {
        "private"
    }
    protected doSomethingProtected() {
        "protected"
    }
}

...这些 Bob 方法之一被称为将通过未设置 SecurityManager 的设置通过,但设置失败。它所使用的包也无关紧要。 Bob 是否在子包中(例如), @PackageScope :只有给 Main.main 给出 @CompileStatic 才有帮助(请参见题)。
我也不清楚如何使用这样设置的 SecurityManager 可以做什么:是否可以强制执行 private 受保护的(或打包私有)?目前,我只是不知道并且将不得不进行调查。

... whichever one of these Bob methods is called it will pass with the SecurityManager not set, but fail with it set. It also doesn't matter which package it's in. Nor does it matter whether Bob is in a subpackage (for example), with @PackageScope: it is only if Main.main is given @CompileStatic that this will help (see referenced question). I'm also not clear about precisely what you can do with a SecurityManager set in this way: is it possible to enforce private or protected (or package-private) in some way? At the moment I just don't know and will have to investigate.

关于其他建议,这很有趣,但实际上并没有否认可见性,因为建议。您还需要在类 A 中包括以下方法:

As for the other suggestion, it's intriguing, but doesn't in fact deny "visibility" as suggested. You'd also need to include the following method in class A:

def getI() {
    throw new Exception()
}

之后是的,所有其他类的可见性都被拒绝,无论是否在同一程序包中,,而且这些私有元素甚至对于同一类的其他对象也不可见(!-与Java不同)。从这个意义上讲,它确实提供了非常严谨的隐私。但对我来说,这也是一个小技巧。对于这个 GroovyObjectSupport 类或它的作用,我还不太清楚,因此必须对其进行调查。最后,实际上没有为这些字段提供 private 修饰符。就像我说的那样,Groovy中 private 的唯一功能是拒绝这些字段对达盖特类 A 的子类可见。在这里。

After that, yes, visibility is denied to every other class, whether in the same package or not, and also these "private" elements are not even visible to other objects of the same class (! - unlike Java). In that sense it does indeed deliver a very Draconian privacy. But to me it's also a bit of a hack. I'm not quite clear about this GroovyObjectSupport class or what it does, and will have to investigate it. Finally, there is little point in actually giving these fields the private modifier. As I said, the ONLY function of private in Groovy is to deny visibility of these fields to subclasses of daggett's class A here.

在超级德拉科人和骇客的私人或不受限制的公开之间只有一个鲜明的选择,显然代表了可见度选择中的相当贫困。与Java相比,在Java中,您不仅具有受保护的,而且还具有程序包私有的(当然,是的,是的,是的,当然,要使用反射...),而 private 字段对相同类的其他对象可见。

Having only a stark choice between a super-Draconian and hackish "private", or "unrestrictedly public", clearly represents a considerable "impoverishment" of choice of visibility compared to Java, where you have not only protected but also package-private (subject, yes yes yes, of course, to use of reflection...), and where private fields are visible to other objects of the same class.

推荐答案

SecurityManager


不要运行 GroovyConsole 中的代码。



def sm = new SecurityManager()
System.setSecurityManager(sm)
//without previous lines the following code will run successfully
println new ByteArrayOutputStream().buf

这将引发以下异常

Caught: java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessDeclaredMembers")
java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.codehaus.groovy.tools.GroovyStarter.rootLoader(GroovyStarter.java:109)
        at org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:131)
Caused by: java.lang.ExceptionInInitializerError
        at groovy.ui.GroovyMain.run(GroovyMain.java:397)
        at groovy.ui.GroovyMain.process(GroovyMain.java:370)
        at groovy.ui.GroovyMain.processArgs(GroovyMain.java:129)
        at groovy.ui.GroovyMain.main(GroovyMain.java:109)
        ... 6 more
Caused by: java.security.AccessControlException: access denied ("java.util.logging.LoggingPermission" "control")
        at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
        at java.security.AccessController.checkPermission(AccessController.java:884)
        at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
        at java.util.logging.LogManager.checkPermission(LogManager.java:1586)
        at java.util.logging.Logger.checkPermission(Logger.java:422)
        at java.util.logging.Logger.setUseParentHandlers(Logger.java:1799)
        at org.codehaus.groovy.runtime.StackTraceUtils.<clinit>(StackTraceUtils.java:57)
        ... 10 more

通过 getProperty & setProperty

control access with getProperty & setProperty

class A extends GroovyObjectSupport{
    private int i=555
    private int j=666
    def f(){
        println "i=$i j=$j"
    }
    Object getProperty(String name){
        if(name in ['i'])throw new Exception("Access to property `$name` is denied")
        return super.getProperty(name)
    }
}
def a=new A()
a.f()
println "a.j = ${a.j}"
println "a.i = ${a.i}"

这将允许访问成员 j ,但不允许访问给课外的成员 i

this will allow access to member j but not to the member i outside of class.

输出:

i=555 j=666
a.j = 666
Exception thrown

java.lang.Exception: Access to property `i` is denied
  ...

这篇关于Groovy中的信息隐藏(使用闭包或命名约定?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆