2

このようなものを想像してください:

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 }

この場合、テストはインターフェイスに適用されるため、「サポート」の概念は二次的ですが関連性があります(したがって、言語は、すべての実装が合格する必要があるインターフェイステストと、実装プライベートに固有の実装テストを区別します。

しかし、ここで伝えたい重要なアイデアは、アクセス制御のセマンティクスです。「accessfrom」キーワードを持つA.sumは、メソッドB.calculatorからのみ呼び出すことができることに注意してください。それ以外のものは、コンパイル時エラーとして検出されます。ここでの考え方は、よりきめ細かい方法でアーキテクチャの制約を適用することです。「accessfrom」を追加しなかった場合、または「access from *」を追加しただけの場合は、メソッドをどこからでも呼び出せるようにするデフォルトの動作を意味します。どのようなアーキテクチャ上の制約がありますか?レイヤードデザインを行うときに手動で適用される種類:レイヤーA(最低レベル)はレイヤーB(中間レベル)から使用され、レイヤーB(中間レベル)はレイヤーC(高レベル)から使用されます。ただし、レイヤーBはレイヤーAからアクセスできず、レイヤーCはAとBのどちらからもアクセスできません。

質問:上記のセマンティクスをサポートする言語(ソース間中間言語を含む)を知っていますか?この種のセマンティクスが逆効果であるか、危険であるか、または単に悪い設計を助長するかどうかを議論するための追加のポイント

更新:この種の制限には、もう1つの非常に重要なユースケースがあります。

イベント駆動型プログラミング:通常、イベントの問題は、イベントの実行が多すぎる傾向があり、イベントの依存関係のチェーンを理解するのが難しい場合があることです。

したがって、たとえば、イベントハンドラーには、対話できる表示可能なクラスの特定のセット(または、逆に、触れることができないオブジェクトの特定のセット)のみがあると定義できます。

4

3 に答える 3

2

これは、オブジェクト機能モデルの特殊なケースのように聞こえます。おそらく、これを何らかの方法で実装する言語があります。

同様に、「メソッドレベルのセキュリティ」をグーグルで検索すると、エンタープライズJavaコミュニティが作り上げたと思われるいくつかのことがわかりました。このアプローチをメソッド呼び出しだけに特化するのは、ちょっと無意味だと思います。これを行う非常に正当な理由がない限り、それはおそらく悪い考えだと思います。何らかの理由でそれを行うことに本当に興味がある場合、実際のモデルは、呼び出し元が許可されたセットにあることを受信者に確認させることです。

いずれにせよ、これは基本的にほとんどのプログラミングモデルをかなりひどく壊しています。前提条件とクラス不変条件を適用して、メソッドの呼び出し(どこからでも!)が意味のある、または正常に動作することを確認する方がはるかに良いでしょう。メソッドの順序付けを強制するために使用している場合は、不変チェック(静的または実行時)、またはInterfaceAutomataなどの理論モデルを使用して実現できます。

于 2010-08-15T15:30:57.867 に答える
1

Java は、ほとんど同じことをサポートしています。

まず第一に、フィールドとメソッドの可視性は実行時に強制されます。特権のないコードがこれをバイパスすることはできません。

独自の特権を作成して、コードの特定の部分に付与することもできます。たとえば、ファイルを開くには、ファイルにアクセスするコードがそのファイルを必要FilePermissionとします。ただし、任意の種類のアクセス許可を作成できます。合計する前SumPermissionCalculatorチェックするアクセス許可を作成し、必要なクラスにのみ付与することができます。通常、クラス全体は単一のソースから取得されるため、保護ドメインは、クラス内の個々のメソッドではなく、複数のクラスにまたがります。実際、モデルはあなたが提案したものよりも深くなります。セキュリティ チェックに至るまでのスタック (スレッド作成の履歴を含む) 上のすべてのクラスには、アクセス許可が必要です。SumPermission、セキュリティチェックに失敗します。もちろん、これはデフォルトにすぎません。アクセス許可が必要なことを行うときはいつでも、doPrivilegedブロックを使用して、次のチェックで、あなたと呼び出し元の両方ではなく、あなたのアクセス許可のみをチェックするように指示できます。

ただし、Java の現在のデフォルトのセキュリティ スキームには多くの制限があります。1 つには、信頼されていないコードは、そのアクセス許可を細分化したり、ネストされた信頼されていないコードに対して独自のアクセス許可を定義したりすることはできません。また、ブロックする信頼できないコードを防ぐのも面倒です

Eをチェックしてみてください。特に、オブジェクト機能モデルに従います。相互に信頼されていないコードが安全にやり取りできるように作成されており、デッドロックの問題を防ぐための言語レベルの構造があります。

Java で相互に信頼されていないコード間で堅牢な動作を実装することは完全に可能で実行可能ですが、E を使用するとおそらく作業がはるかに簡単になり、JVM で実行されるため、Java ライブラリと、Java を使用する他の言語のライブラリを引き続き使用できるはずです。 JVM。

于 2010-09-06T16:38:03.587 に答える
0

構文は異なりますが、これは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)

モジュールを mix-in として使用する場合は、モジュールとselfなるクラスに対応しincludeます。 caller現在のコールスタックを返し、caller.firstコールスタックの最初のエントリ (つまり、これを呼び出した関数) を取得します。

于 2010-08-11T20:22:18.063 に答える