Design patterns 具有粒度方法和属性访问的编程语言

Design patterns 具有粒度方法和属性访问的编程语言,design-patterns,architecture,programming-languages,access-control,layered,Design Patterns,Architecture,Programming Languages,Access Control,Layered,想象一下这样的情景: import class B.*; interface A supports A.testSum { int sum( int a , int b ) access from B.calculator; testSum() { Assert(sum(1,1)==2); } ........ class B ... { void calculator() { A.sum(3,5); //ok } void someOtherMethod()

想象一下这样的情景:

import class B.*;


interface A supports A.testSum
{
   int sum( int a , int b ) access from B.calculator;

   testSum() { Assert(sum(1,1)==2); }

........


class B ...
{
  void calculator() {  A.sum(3,5); //ok }
  void someOtherMethod() { A.sum(0,3); //compile error }
“支持”的概念是次要的,但与此相关,因为在这种情况下,测试适用于接口(因此语言将区分所有实现都必须通过的接口测试和特定于实现私有的实现测试)

但我想在这里传达的重要思想是访问控制语义;请注意,带有“access from”关键字的A.sum只能从方法B.calculator调用。其他任何内容都会被检测为编译时错误。这里的思想是以更细粒度的方式强制实施架构约束。如果不添加“access from”或者只是添加了“从*访问”,这意味着默认行为允许从任何地方调用该方法。什么样的体系结构约束?好的,在进行分层设计时手动执行的约束类型:从B层(中间层)使用a层(最低层),从C层(高层)使用B层(中间层)但B层不能从A层访问,C层不能从A层或B层访问,但在其他方面是公共的(可能是最终用户将直接访问的)

问:您知道支持上述语义的任何语言(包括源代码到源代码的中间语言)吗?讨论这种语义是否会适得其反、危险或只会鼓励糟糕的设计的额外要点

更新:这种限制还有另一个非常重要的用例:

事件驱动编程:通常事件的问题是,事件往往做得太多,理解事件的依赖链可能会变得很棘手


例如,我们可以定义一个事件处理程序只有一组可以交互的可见类(或者相反,它不能接触的一组对象)

这在Ruby中是可以做到的,尽管语法不同

module T
    def check
        raise unless self.is_a?(Ca)
        raise unless %r{in `good_func'} =~ caller.first #`
        true
    end
end

class Ca
    include T
    def good_func
        check
    end
    def bad_func
        check
    end
end

class Cb
    include T
    def good_func
        check
    end
    def bad_func
        check
    end
end

a = Ca.new
b = Cb.new

a.good_func
=> true
a.bad_func
=> (RuntimeError)

b.good_func
=> (RuntimeError)
b.bad_func
=> (RuntimeError)

将模块用作混合模块时,
self
对应于
包含该模块的类。
caller
返回当前调用堆栈,并
caller。first
获取调用堆栈上的第一个条目(即调用此项的函数).

这听起来像是的一个特例。也许有一些语言以某种方式实现了这一点

类似地,快速搜索“方法级安全性”让我了解了一些企业Java社区似乎已经捏造出来的东西。我认为,将这种方法专门用于方法调用是毫无意义的。除非你有很好的理由这样做,否则我认为这可能是个坏主意。如果你真的出于某种原因对这样做感兴趣,那么真正的模型应该是接收方检查调用源是否在某个允许的集合中


在任何情况下,这基本上严重破坏了大多数编程模型。您最好强制执行前提条件和类不变量,以确保任何方法调用(从任何地方!)都有意义或行为良好。如果您使用它强制方法排序,则可以使用不变量检查来实现(静态或运行时)或理论模型,例如。

Java支持几乎相同的东西

首先,字段和方法的可见性是在运行时强制执行的,非特权代码不可能绕过这一点

您还可以创建自己的权限,并将其授予代码的某些部分。例如,要打开文件,要访问文件的代码需要该文件的
FilePermission
。您可以创建任何类型的权限,但也可以创建名为
sumppermission
的权限,该权限
Calculator
求和前进行检查,并仅将其授予您想要的任何类。保护域跨越类,而不是类中的单个方法,因为整个类通常是从单个源获取的。该模型实际上比您提出的模型更深入。堆栈上的每个类(包括线程创建的历史记录)进行安全检查之前必须具有权限,因此,如果某些不受信任的代码调用具有
sumpowermission
权限的代码,它将无法通过安全检查。当然,这只是默认情况,每当您执行任何需要权限的操作时,您都可以使用
doPrivileged
块,告诉即将进行的检查仅检查您的权限而不是你和你的来电者

然而,Java中当前的默认安全方案有很多限制。首先,不受信任的代码无法细分其权限或为嵌套的不受信任的代码定义自己的权限。此外,防止不受信任的代码阻塞也是一件痛苦的事

您可能需要签出。特别是,它遵循对象功能模型。它是为相互不信任的代码安全交互而设计的,并且具有语言级构造以防止死锁问题


在Java中实现相互不信任的代码之间的健壮行为是完全可能和可行的,但E可能会使您的工作更容易,并且在JVM上运行,因此您应该仍然能够使用Java库和使用JVM的任何其他语言的库。

您必须原谅语法的突出之处,回击是扔掉它。第四行末尾的注释是没有意义的,只是为了让语法荧光笔回到正轨。有没有更干净的方法来转义这个字符?我忘记了所有的标记规则…语法差异是可以的,只要语义相同。但是这个检查会在运行时发生,对吗?所以我们每次调用函数时,都要确定约束的日期,但在编译时检测冲突并避免不必要的入侵会更令人满意。运行时开销会认为,如果函数