Groovy中的信息隐藏(使用闭包?命名约定?)

时间:2018-06-12 20:25:24

标签: groovy encapsulation information-hiding

这是因为我从2014年尝试找到this question的答案失败了。

我不清楚Groovy中是否有一些技术可以使用闭包,特别是隐藏信息。我只能说,如果有关于这种技术的信息出现在那里,它就是一个完美的例子,确切地说,是信息隐藏":我找不到它!

但是我没想到我现在理解的是,绝对没有尝试隐藏信息(或假装在Java中 - 考虑到反射技术)。这似乎是设计上的,但也是由于Groovy的动态性质的要求。例如,在引用的问题中提到的@CompileStatic似乎更多地是关于类型检查而不是其他任何东西。

但是在Python中,例如,有一个约定(我假设仍然使用)来制作"字段,这些字段被认为是私有的"以双下划线开头。我从来没有听说过有人和Groovy谈过这个问题。

Aren的信息隐藏和封装,或者至少是鼓励有条理地使用“亲密国家”的惯例。对象,好东西?任何Groovy专家都在评论吗?

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

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也不重要:它只是{{1}给予Main.main这将有所帮助(参见引用的问题)。 我还不清楚您可以通过这种方式准确地使用@CompileStatic集合做些什么:是否可以在某些方面强制执行SecurityManagerprivate(或包私有)办法?目前我还不知道并且必须进行调查。

至于其他建议,它很有趣,但实际上并没有否认"可见性"如建议。您还需要在课程protected中包含以下方法:

A

之后,是的,可见性被拒绝给所有其他类,无论是否在同一个包中,以及这些"私人"对于同一类的其他对象来说,元素甚至都不可见(! - 与Java不同)。从这个意义上说,它确实提供了非常严肃的隐私。但对我而言,这也是一个黑客攻击。我不太清楚这个def getI() { throw new Exception() } 课程或它的作用,并且必须对其进行调查。最后,实际上给这些字段GroovyObjectSupport修饰符没有什么意义。正如我所说,Groovy中private的唯一功能是拒绝这些字段对daggett的类private的子类的可见性。

在超级严厉和苛刻的私人"或者#34;不受限制的公众"之间只有一个明显的选择,显然代表了一个相当大的“贫困”#34;与Java相比,可见性的选择,你不仅有A,还有包私有(主题,是,是的,当然是使用反射...),以及protected字段对于同一类的其他对象是可见的。

1 个答案:

答案 0 :(得分:0)

<强>安全管理器

  

请勿运行GroovyConsole的代码。只能从groovy命令行。

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和&amp ;;控制访问权限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

输出:

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

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