質問

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

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からのみ呼び出すことができることに注意してください。他のすべては、コンパイル時間エラーとして検出されます。ここでのアイデアは、より詳細な方法でアーキテクチャの制約を実施することです。 「アクセス」を追加しなかった場合、または「 *」から「アクセス」を追加しなかった場合、メソッドをどこからでも呼び出すことを許可するデフォルトの動作を意味します。どのようなアーキテクチャの制約ですか?まあ、層状設計を実行するときに手動で強制される種類:レイヤーA(最低レベル)は、レイヤーB(中間レベル)から使用され、レイヤーC(高レベル)から使用されます。ただし、レイヤーBはレイヤーAからアクセスできず、レイヤーCはAまたはBのどちらからもアクセスできませんが、それ以外の場合は公開されません(エンドユーザーが直接アクセスできるものかもしれません)

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

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

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

したがって、たとえば、イベントハンドラーには対話できる特定の目に見えるクラスのセットしか持っていないことを定義できます(または逆に、触れられないオブジェクトの特定のセット)

役に立ちましたか?

解決

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

まず第一に、フィールドとメソッドの可視性は実行時に実施されます。これは、恵まれないコードがこれをバイパスすることは不可能です。

また、独自の特権を作成し、コードの特定の部分に付与することもできます。たとえば、ファイルを開くには、ファイルにアクセスしたいコードが必要です FilePermission そのファイルの場合。あなたはあなたが望むあらゆる種類の許可を得ることができます、それは許可を与えることが可能です SumPermission どれの Calculator 合計する前にチェックし、必要なクラスにのみ付与します。クラス全体が一般に単一のソースから取得されるため、クラス内の個々の方法ではなく、クラスにまたがって保護ドメインが及びます。実際、モデルはあなたが提案したものよりも深くなります。セキュリティチェックに至るまでのスタック上のすべてのクラス(スレッド作成の履歴を含む)には許可が必要なので、信頼されていないコードがあなたのコードを呼び出している場合 SumPermission, 、セキュリティチェックに失敗します。もちろん、これはデフォルトのみです。許可が必要なことを何でもするときはいつでも、 doPrivileged ブロック、今後のチェックに、自分の発信者と発信者の両方ではなく、許可のみをチェックするように伝えます。

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

あなたはチェックアウトしたいかもしれません e. 。特に、オブジェクト能力モデルに従います。相互に信頼されていないコードが安全に相互作用するために作成されており、デッドロックの問題を防ぐための言語レベルの構成要素があります。

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

他のヒント

これは特別なケースのように聞こえます オブジェクトキャピールモデル. 。おそらく、何らかの形でこれを実装する言語があります。

同様に、「メソッドレベルのセキュリティ」のための簡単なGoogleは、エンタープライズJavaコミュニティが調理したように見えるいくつかのことに私を導きました。このアプローチを専門とすることは、メソッドコールだけに特化することは無意味だと思います。これを行う理由がない限り、おそらく悪い考えだと思います。何らかの理由でそれを行うことに本当に興味がある場合は、実際にモデルはレシーバーに呼び出しソースが許可されたセットであることを確認することです。

いずれにせよ、これは基本的にほとんどのプログラミングモデルをかなりひどく破壊しています。前提条件とクラスの不変性を実施して、(どこからでも)メソッドの呼び出しが意味があるか、行儀が良いことを確認する方がよいでしょう。それを使用してメソッド順序を強制する場合、それは不変のチェック(静的または実行時)、またはなどの理論モデルを使用して達成できます。 インターフェイスオートマトン.

これは、異なる構文がありますが、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 クラスに対応します includesモジュール。 caller 現在のコールスタックを返します caller.first CallStackの最初のエントリ(つまり、これと呼ばれる関数)を取得します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top